Loading

Redis

1. 概念:

redis是一款高性能的NOSQL系列的非关系型数据库

1.1.什么是NOSQL


NoSQL(NoSQL = Not Only SQL),意即“不仅仅是SQL”,是一项全新的数据库理念,泛指非关系型的数据库。
 随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。

1.1.1.    NOSQL和关系型数据库比较

优点:
   1)成本:nosql数据库简单易部署,基本都是开源软件,不需要像使用oracle那样花费大量成本购买使用,相比关系型数据库价格便宜。
   2)查询速度:nosql数据库将数据存储于缓存之中,关系型数据库将数据存储在硬盘中,自然查询速度远不及nosql数据库。
   3)存储数据的格式:nosql的存储格式是key,value形式、文档形式、图片形式等等,所以可以存储基础类型以及对象或者是集合等各种格式,而数据库则只支持基础类型。
   4)扩展性:关系型数据库有类似join这样的多表查询机制的限制导致扩展很艰难。

缺点:
    1)维护的工具和资料有限,因为nosql是属于新的技术,不能和关系型数据库10几年的技术同日而语。
    2)不提供对sql的支持,如果不支持sql这样的工业标准,将产生一定用户的学习和使用成本。
    3)不提供关系型数据库对事务的处理。

1.1.2.    非关系型数据库的优势:
      1)性能NOSQL是基于键值对的,可以想象成表中的主键和值的对应关系,而且不需要经过SQL层的解析,所以性能非常高。
      2)可扩展性同样也是因为基于键值对,数据之间没有耦合性,所以非常容易水平扩展。

 1.1.3.    关系型数据库的优势:
       1)复杂查询可以用SQL语句方便的在一个表以及多个表之间做非常复杂的数据查询。
       2)事务支持使得对于安全性能很高的数据访问要求得以实现。对于这两类数据库,对方的优势就是自己的弱势,反之亦然。

1.1.4.    总结
关系型数据库与NoSQL数据库并非对立而是互补的关系,即通常情况下使用关系型数据库,在适合使用NoSQL的时候使用NoSQL数据库,
让NoSQL数据库对关系型数据库的不足进行弥补。
一般会将数据存储在关系型数据库中,在nosql数据库中备份存储关系型数据库的数据

1.2.主流的NOSQL产品

 •    键值(Key-Value)存储数据库
       相关产品: Tokyo Cabinet/Tyrant、Redis、Voldemort、Berkeley DB
       典型应用: 内容缓存,主要用于处理大量数据的高访问负载。 
       数据模型: 一系列键值对
       优势: 快速查询
       劣势: 存储的数据缺少结构化
 •    列存储数据库
      相关产品:Cassandra, HBase, Riak
       典型应用:分布式的文件系统
       据模型:以列簇式存储,将同一列数据存在一起
       优势:查找速度快,可扩展性强,更容易进行分布式扩展
       劣势:功能相对局限
•    文档型数据库
        相关产品:CouchDB、MongoDB
         典型应用:Web应用(与Key-Value类似,Value是结构化的)
         数据模型: 一系列键值对
          优势:数据结构要求不严格
          劣势: 查询性能不高,而且缺乏统一的查询语法
•    图形(Graph)数据库
           相关数据库:Neo4J、InfoGrid、Infinite Graph
           典型应用:社交网络
            数据模型:图结构
            优势:利用图结构相关算法。
            劣势:需要对整个图做计算才能得出结果,不容易做分布式的集群方案。

1.3 什么是Redis

Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库,官方提供测试数据,50个并发执行100000个请求,读的速度是110000次/s,写的速度是81000次/s ,且Redis通过提供多种键值数据类型来适应不同场景下的存储需求,目前为止Redis支持的键值数据类型如下:
     1) 字符串类型 string
     2) 哈希类型 hash
     3) 列表类型 list
     4) 集合类型 set
     5) 有序集合类型 sortedset
1.3.1 redis的应用场景
•    缓存(数据查询、短连接、新闻内容、商品内容等等)
•    聊天室的在线好友列表
 •    任务队列。(秒杀、抢购、12306等等)
 •    应用排行榜
•    网站访问统计
•    数据过期处理(可以精确到毫秒
•    分布式集群架构中的session分离

 

 

2. 下载安装

1. 官网:https://redis.io
2. 中文网:http://www.redis.net.cn/

Win版 :https://github.com/MicrosoftArchive/redis
3. 解压直接可以使用:
 * redis.windows.conf:配置文件

Redis的常用基本配置
配置项 示例 说明
daemonize daemonize yes 是否启用后台运行(守护线程),默认no
port port 6379 设置端口号,默认6379
logfile logfile 日志文件 设置日志文件
databases databases 255 设置redis数据库总量
dir dir 数据文件目录 设置数据文件存储目录
requirepass requirepass 12345 设置使用密码
pidfile pidfile 路径 指定保存redis进程id的文件路径
protect-mode protect-mode yes 设置开启保护模式
bind bind 127.0.0.1 在保护模式下允许访问redis的主机ip
requirepass requirepass 123456

设置访问密码   auth 123456

database database 16

设置redis中数据库的个数

 * redis-cli.exe:redis的客户端
* redis-server.exe:redis服务器端

linux安装

1.安装gcc工具   yum install -y  gcc

2.解压 tar -zxvf redis-6.2.5

3.进入redis-6.2.5文件夹   编译  make 

4.安装 make install

5.运行  进入src文件夹 执行 redis-server

后台运行  redis-server&

6.启动客户端   redis-cli

7.关闭   

查询   pidlsof -i :6379

关闭   kill -9 34932

8.通过配置文件修改端口

cat -n redis.conf|grep port 

vim +98 redis.conf

9.启动时用刚修改的配置文件

src/redis-server redis.conf

3. 命令操作

1. redis的数据结构:

* redis存储的是:key,value格式的数据,其中key都是字符串,value有5种不同的数据结构

 * value的数据结构:
     1) 字符串类型 string
     2) 哈希类型 hash : map格式  
     3) 列表类型 list : linkedlist格式。支持重复元素
     4) 集合类型 set  : 不允许重复元素
     5) 有序集合类型 sortedset:不允许重复元素,且元素有顺序

2. 字符串类型 string

指令 说明
set key value 存储
get key 获取
del key 删除

mset key1 hello  key2 world

 mget key1 key2

批量操作

incr ke    y给key对应的值+1   incrby key 9   值+9

decr key 给key对应的值-1

自增自减
setex key 10 whaha   10秒后删除 过期时间
setnx key v6 key不存在时插入,存在不进行操作
append key wahaha 追加
strlen key 查看key对应值的操作

 

3. 哈希类型 hash

指令 说明
hset key field value 存储
hget key field 根据field取valus
hmset key f1 v1[f2 v2...] 批量添加
hmget key f1 f2 批量获取
hincrby key f v  给指定的字段值自增
hgettall key 取出key对应的map的所有的field和value
hkeys key 取出key对应的map所有field
hvals key 取出key对应的map所有value
hexists key field 检查key对应的map中是否存在指定的field
hlen key 获取key对应的map中键值对的个数
hsetnx key filed value 在key对应的map中新增键值对,只有field不存在才执行成功

 

4. 列表类型

指令 说明
lpush key value 对key对应的列表左边添加数据(如果key对应的列表不存在,则创建此表)
rpush key value 对key对应的列表右边边添加数据(如果key对应的列表不存在,则创建此表)
lpushx key value 对key对应的列表左边添加数据(如果key对应的列表不存在,则不进行操作)
rpushx key value 对key对应的列表右边添加数据(如果key对应的列表不存在,则不进行操作)

lpop key 从列表左边取值

rpop key 从列表右边取值

取值 (出栈)
lset key index value 修改key对应的列表 index索引的值 (从左往右,从0开始)
 lrange key start stop 查看key对应的列表索引在start到stop的范围值(列表数据不会改变)
 lindex key index 查看key对应的列表中指定索引的值(列表数据不会改变)
 llen key 获取key对应的列表中的个数
 ltrim key start stop 截取key对应列表中索引在[start,stop]范围的数据,删除超过此范围的数据
 rpoplpush key1 key2 从key1列表的右侧出栈一个数据入栈到key2列表左侧

 

5. 集合类型 set : 不允许重复元素

指令 说明
sadd key value [value...] 存储数据:将值存储在key对应的集合中
smembers key 获取数据 获取key对应集合的全部数据
spop key 随机获取key对应的集合中的一个数据(出栈)
sinter key1 key2 交集
sunion key1 key2 并集
sdiff key1 key2 差集
srem key value 从key对应的集合中移除指定元素
sismember key value  检查key对应的集合中食肉存在指定的值

 

6. 有序集合类型 sortedset:

不允许重复元素,且元素有顺序.每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

指令 说明
zadd key score member [score member....] 存储数据(score存储位置必须是数字,member元素不能重复)
zrange key start stop 查看key对应的有序集合中索引[start,stop]数据  按照score小到大
zscore key member 查看member元素在key对应的有序集合中的索引
zcard key 获取key对应的zset中的元素
zcount key min  max 获取key对应zset中,score在[min,max]范围内的member个数
zrem key member 从key对应的zset中移除指定的member
zrerange key start stop 查看key的有序集合索引[start,stop]数据 按照score大到小

7. key相关指令

指令 说明
keys pattern 查看redis中满足pattern规则的key(keys *)
exists key 查看指定的key是否存在
del key 删除指定的key-value对
ttl key 获取当前key的存活时间(没有设置过期返回-1,设置过期并已经过期返回-2)

expire key seconds

pexpire key milliseconds

设置键值对过期时间
persist key 取消键值对过期时间
type key  获取键对应的value的类型

8.db常用指令

默认16个db,0-15

指令 说明
select index 切换数据库
move key index 将键值对从当前db移动到目标db
flashall 删除当前数据库所有值 
flushdb  删除所有数据库所有值 
dbsizee 查看当前db中key-value个数
lastsave 获取最后一次操作时间

4. 持久化

redis是一个内存数据库,当redis服务器重启,获取电脑重启,数据会丢失,我们可以将redis内存中的数据持久化保存到硬盘的文件中。
redis持久化机制:
1. RDB(Redis DataBase):默认方式
满足特定的redis操作时,将内存中的数据已快照的形式存储到rdb文件中

快照是数据存储的某一时刻的状态记录,不是某一时刻的增量         

              

redis.windwos.conf文件
#   after 900 sec (15 min) if at least 1 key changed
save 900 1
#   after 300 sec (5 min) if at least 10 keys changed
save 300 10
#   after 60 sec if at least 10000 keys changed
save 60 10000

rdbcompression yes  持久化开关

dbfilename  dump.rdb默认存储文件

重新启动redis服务器,并指定配置文件名称redis-server.exe redis.windows.conf  

缺点:

  • 若果出现故障,存在数据丢失的风险 
  • RDB采用的数据快照形式持久化,不适合实时性持久化
  • 若果信息量巨大,在RDB持久化过程中生产数据快照的子进程执行时间过长,会导致redis卡顿,因此save时间不宜过短

优点:

  • 数据量小时,执行速度快
  • 由于是以数据快照的形式保存的,我们可以挺过拷贝rdb文件轻松实现redis数据移植

   
2. AOF(append only file):当达到特定的触发条件时,将redis执行的写操作命令存储到aof文件中(增量操作).

日志记录的方式,默认不开启,当redis重启时会执行aof的指令恢复

redis.windwos.conf文件
appendonly no(关闭aof) --> appendonly yes (开启aof)
                    
# appendfsync always : 每一次操作都进行持久化
appendfsync everysec : 每隔一秒进行一次持久化
# appendfsync no     :不人为设定

appendfilename appendonly.aof   默认存放文件

AOF细节:

  • aof文件也可以通过拷贝aof文件进行redis数据移植
  • aof存储的指令,会对指令进行整理,在数据量小时,rdb(快照)快.
  • aof是对指令文件进行增量更新,更适合实时性持久化
  • 官方建议同时开启2中持久化策略,若果同时存在aof和rdb文件情况下,aof优先还原

5. Java客户端 Jedis

* Jedis: 一款java操作redis数据库的工具.
* 使用步骤:
     1. 下载jedis的jar包
     2. 使用

                //1. 获取连接
                Jedis jedis = new Jedis("localhost",6379);
                   //2. 操作
                   jedis.set("username","zhangsan");
                //3. 关闭连接
                jedis.close();

* Jedis操作各种redis中的数据结构

1) 字符串类型 string

set

get

                //1. 获取连接
                Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
                //2. 操作
                //存储
                jedis.set("username","zhangsan");
                //获取
                String username = jedis.get("username");
                System.out.println(username);
        
                //可以使用setex()方法存储可以指定过期时间的 key value
                jedis.setex("activecode",20,"hehe");//将activecode:hehe键值对存入redis,并且20秒后自动删除该键值对
        
                //3. 关闭连接
                jedis.close();

2) 哈希类型 hash : map格式  

hset
hget
hgetAll

                //1. 获取连接
                Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
                //2. 操作
                // 存储hash
                jedis.hset("user","name","lisi");
                jedis.hset("user","age","23");
                jedis.hset("user","gender","female");
        
                // 获取hash
                String name = jedis.hget("user", "name");
                System.out.println(name);
        
        
                // 获取hash的所有map中的数据
                Map<String, String> user = jedis.hgetAll("user");
        
                // keyset
                Set<String> keySet = user.keySet();
                for (String key : keySet) {
                    //获取value
                    String value = user.get(key);
                    System.out.println(key + ":" + value);
                }
        
                //3. 关闭连接
                jedis.close();

3) 列表类型 list : linkedlist格式。支持重复元素

lpush / rpush
lpop / rpop
lrange start end : 范围获取

              //1. 获取连接
                Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
                //2. 操作
                // list 存储
                jedis.lpush("mylist","a","b","c");//从左边存
                jedis.rpush("mylist","a","b","c");//从右边存
        
                // list 范围获取
                List<String> mylist = jedis.lrange("mylist", 0, -1);
                System.out.println(mylist);
                
                // list 弹出
                String element1 = jedis.lpop("mylist");//c
                System.out.println(element1);
        
                String element2 = jedis.rpop("mylist");//c
                System.out.println(element2);
        
                // list 范围获取
                List<String> mylist2 = jedis.lrange("mylist", 0, -1);
                System.out.println(mylist2);
        
                //3. 关闭连接
                jedis.close();

4) 集合类型 set  : 不允许重复元素

sadd
smembers:获取所有元素

                //1. 获取连接
                Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
                //2. 操作
        
        
                // set 存储
                jedis.sadd("myset","java","php","c++");
        
                // set 获取
                Set<String> myset = jedis.smembers("myset");
                System.out.println(myset);
        
                //3. 关闭连接
                jedis.close();

5) 有序集合类型 sortedset:不允许重复元素,且元素有顺序

zadd
zrange

          //1. 获取连接
                Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
                //2. 操作
                // sortedset 存储
                jedis.zadd("mysortedset",3,"亚瑟");
                jedis.zadd("mysortedset",30,"后裔");
                jedis.zadd("mysortedset",55,"孙悟空");
        
                // sortedset 获取
                Set<String> mysortedset = jedis.zrange("mysortedset", 0, -1);
        
                System.out.println(mysortedset);
        
        
                //3. 关闭连接
                jedis.close();

6.jedis连接池: JedisPool

* 使用:
 1. 创建JedisPool连接池对象
 2. 调用方法 getResource()方法获取Jedis连接
  

                  //0.创建一个配置对象
                    JedisPoolConfig config = new JedisPoolConfig();
                    config.setMaxTotal(50);
                    config.setMaxIdle(10);
            
                    //1.创建Jedis连接池对象
                    JedisPool jedisPool = new JedisPool(config,"localhost",6379);
            
                    //2.获取连接
                    Jedis jedis = jedisPool.getResource();
                    //3. 使用
                    jedis.set("hehe","heihei");
            
            
                    //4. 关闭 归还到连接池中
                    jedis.close();

jedis详细配置.properties

#最大活动对象数     
redis.pool.maxTotal=1000    
#最大能够保持idel状态的对象数      
redis.pool.maxIdle=100  
#最小能够保持idel状态的对象数   
redis.pool.minIdle=50    
#当池内没有返回对象时,最大等待时间    
redis.pool.maxWaitMillis=10000    
#当调用borrow Object方法时,是否进行有效性检查    
redis.pool.testOnBorrow=true    
#当调用return Object方法时,是否进行有效性检查    
redis.pool.testOnReturn=true  
#“空闲链接”检测线程,检测的周期,毫秒数。如果为负值,表示不运行“检测线程”。默认为-1.  
redis.pool.timeBetweenEvictionRunsMillis=30000  
#向调用者输出“链接”对象时,是否检测它的空闲超时;  
redis.pool.testWhileIdle=true  
# 对于“空闲链接”检测线程而言,每次检测的链接资源的个数。默认为3.  
redis.pool.numTestsPerEvictionRun=50  
#redis服务器的IP    
redis.ip=xxxxxx  
#redis服务器的Port    
redis1.port=6379   

* 连接池工具类

                public class JedisPoolUtils {

                    private static JedisPool jedisPool;
                
                    static{
                        //读取配置文件
                        InputStream is = JedisPoolUtils.class.getClassLoader().getResourceAsStream("jedis.properties");
                        //创建Properties对象
                        Properties pro = new Properties();
                        //关联文件
                        try {
                            pro.load(is);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        //获取数据,设置到JedisPoolConfig中
                        JedisPoolConfig config = new JedisPoolConfig();
                        config.setMaxTotal(Integer.parseInt(pro.getProperty("maxTotal")));
                        config.setMaxIdle(Integer.parseInt(pro.getProperty("maxIdle")));
                
                        //初始化JedisPool
                        jedisPool = new JedisPool(config,pro.getProperty("host"),Integer.parseInt(pro.getProperty("port")));
                
                
                
                    }
                
                
                    /**
                     * 获取连接方法
                     */
                    public static Jedis getJedis(){
                        return jedisPool.getResource();
                    }
                }

 


## 案例:
    案例需求:
        1. 提供index.html页面,页面中有一个省份 下拉列表
        2. 当 页面加载完成后 发送ajax请求,加载所有省份


    * 注意:使用redis缓存一些不经常发生变化的数据。
        * 数据库的数据一旦发生改变,则需要更新缓存。
            * 数据库的表执行 增删改的相关操作,需要将redis缓存数据情况,再次存入
            * 在service对应的增删改方法中,将redis数据删除。

7.SpringBoot整合Jedis

 1.在创建springboot应用时勾选Spring Data Redis

有两个对象

  • RedisTemplate
  • StringRedisTemplate

2.在application.yml配置redis

3.直接在service注入RedisTemplate对象

 

 

 

 

String类型的操作

过期时间

  • 在添加数据是给两个参数,第二个参数就是过期时间
  • stringRedisTemplate.boundValueOps(key).expire(300,TimeUnit.MINUTES)

8.redis做缓存

  • 对数据写操作比较少,但是会频繁的查询的数据适合缓存
  • 对于可能会发生修改,但是数据一致性要求不高的数据也适合缓存

 

 

 

 

 页面静态化 

说明:将数据库每一天数据结合目标生成单独的HTML文件进行存储,一条数据对应一个独立的HTML文件,当用户访问数据时,直接访问不同的静态HTML文件即可.

9.用Redis做缓存存在的问题

9.1缓存击穿

描述:

缓存击穿: 缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力

解决方案:

双重检测锁

 

 

9.2缓存穿透

描述:

缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。

解决方案:

接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;
从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击

9.3缓存雪崩

描述:

缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是, 缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。

解决方案:

缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中
设置热点数据永远不过期

10.Redis高级应用

使用redis作为缓存数据库使用目的是为了提升数据加载速度,降低数据库的访问压力,我们需要保证redis的可用性

  • 主从配置
  • 哨兵模式
  • 集群配置

高可用:保证redis移植处于可用状态,即使出现了故障也有备用方案保证可用性

高并发:一个redis实例已经可以支持多大11w并发读操作或者8.1w并发写操作;但是如果对于有更高的并发需求来说,可以通过 读写分离 集群配置 解决

10.1主从配置

说明:在多个redis实例建立主从关系,当主redis中的数据发送变化,从redis的数据也会同步变化

作用:

  • 数据备份(从redis就是对主redis的备份 ),保证数据安全性
  • 读写分离

配置示例:

#创建文件夹同意管理
mkdir msconf

#排除注释  -v忽略
cat redis.conf | grep -v "#"

#排除注释  -v忽略    # 和空格
cat redis.conf | grep -v "#"|grep -v "^$"

#主机 
cat redis.conf | grep -v "#"|grep -v "^$" > msconf/redis-master.conf

#修改配置文件
#bind 127.0.0.1
protected-mode no  
port 6380
pidfile /var/run/redis_6380.pid
dbfilename dumo_6380.rdb
appendonly yes
appendfilename "appendonly_6380.aof"


#从机
# sed 's/6380/6381/g' redis-master.conf > redis-slave1.congf
cat redis.conf | grep -v "#"|grep -v "^$" > msconf/redis-slave1.conf

cat redis.conf | grep -v "#"|grep -v "^$" > msconf/redis-slave2.conf

修改 redis-slave1.conf和redis-slave2.conf 跟从 主机地址

#添加
slaveof 127.0.0.1 6380

启动三个redis实例

redis-server redis-master.conf&
redis-server redis-slave1.conf&
redis-server redis-slave2.conf&

对主机操作 redis-cli -p 6380

10.2哨兵模式

用于监听主库,当主库宕机之后,从备库(从库)中选举一个转备为主

配置:

哨兵模式配置文件 sentinel.conf

#实现三个redis实例之间的主从配置

#启动哨兵
#redis-sentinel sentinel.conf

#拷贝3个sentinel.conf  
sentlinel-26380.conf
sentlinel-26381.conf
sentlinel-26382.conf

#创建文件夹
mkdir sentinelconf   
#拷贝三份  修改每个配置文件端口
cat sentinel.conf|grep -v "#"|grep -v "^$" > sentinelconf/sentlinel-26380.conf

#修改配置文件
pidfile "/var/run/redis-sentinel-26380.pid"
sentinel monitor mymaster 127.0.0.1 6380 2   #2是哨兵总数一半加1

 监听策略配置 修改配置文件

sentinel down-after-millseconds mymaster 30000

 启动哨兵

#依次启动redis
redis-server redis-master.conf
redis-server redis-slave1.conf
redis-server redis-slave2.conf
#依次启动哨兵
redis-sentinel sentinel-26380.conf
redis-sentinel sentinel-26381.conf
redis-sentinel sentinel-26382.conf

 10.3集群配置

  • Redis集群中每个节点是对等的,无中心结构

  • 数据按照slots分布式存储在不同的redis节点上,节点中的数据可共享,可也动态调整数据(通过数据槽slots)
  • 可扩展性强,可以动态增删节点,最多可扩展1000+节点
  • 集群每个节点通过(主备 哨兵模式)可以保证高可用性

 集群搭建

#1.创建文件夹 到redeis文件夹中
mkdir cluster-conf
#2.拷贝文件
cat redis.conf|grep -v "#"|grep -v "^$" > cluster-conf/redis-7001.conf

#3.修改配置文件redis-7001.conf

#允许远程连接
#bind 127.0.0.1
protected-mode no  
port 7001
pidfile /var/run/redis_7001.pid
dbfilename dumo_7001.rdb
appendonly yes
appendfilename "appendonly_7001.aof"

#4.开启集群模式
cluster-enabled yes

cluster-config-file nodes-7001.conf
#超时
cluster-node-timeout 15000
#守护
daemonized yes

拷贝文件

sed 's/7001/7002/g' redis-7001.conf > redis-7002.conf
sed 's/7001/7003/g' redis-7001.conf > redis-7003.conf
sed 's/7001/7004/g' redis-7001.conf > redis-7004.conf
sed 's/7001/7005/g' redis-7001.conf > redis-7005.conf
sed 's/7001/7006/g' redis-7001.conf > redis-7006.conf

启动6个redis实例

redis-server redis-7001.conf
redis-server redis-7002.conf
redis-server redis-7003.conf
redis-server redis-7004.conf
redis-server redis-7005.conf
redis-server redis-7003.conf
#查看6个实例是否启动
ps -ef |grep redis

启动集群

redis-cli --cluster create 公网ip:7001 ...公网ip:7006 --cluster  -replicas 1

启动时

redis-cli -p 7001 -c

集群管理

#创建集群  replicas表示每个节点有几个备机
redis-cli --cluster create 公网ip:7001 ...公网ip:7006 --cluster  -replicas 1 

#查看集群状态 任何一个节点都可以
redis-cli --cluster info 公网ip:7001

#平衡节点的数据槽数量 任何一个节点都可以
redis-cli --cluster reblance 公网ip:7001

#迁移节点槽 把7001上的数据迁移走
redis-cli --cluster reshard 公网ip:7001
done/all

数据槽都没有数据时可以删除

redis-cli --cluster del-node 公网ip:7001 节点id

 添加节点

redis-cli --cluster add-node 公网ip:7001 集群任何节点

 

11.Redis淘汰策略

Redis时基于内存结结构惊喜数据缓存的,当内存资源消耗完毕,想要有新的数据缓存进来,必修从redis的内存结构中释放一些数据.

redis提供了8种淘汰策略

配置文件

  • LRU :最久最近未使用
  • LFU:最近最少未使用
  • volatile 从设置了过期时间数据中
  • allkeys:所有数据

高频面试题:

1.在项目中redis使用场景

  • 缓存首页数据 

2.Redis持久化策略

3.redis支持的数据类型 

4.如何保证redis的高可用

  • redis支持持久化,同时开启rdb和aof(还是存在丢失数据风险的)
  • redis支持主从配置,配置哨兵实现主备配置
  • redis支持集群,通过集群配置可以保证高并发

5.如何解决redis集群,如何解决redis集群的脑裂问题

6.redis的数据可以设置过期时间,有些key过期后没有及时清除,如何处理

 

 

项目架构的演进

2.1 单体架构

  • 前后端都部署在同一台服务器上(前后端代码都在同一个应用中)

  • 缺点:对静态资源的访问压力也会落在Tomcat上

2.2 前后端分离

 

 

  • 前后端分离:前端和后端分离开发和部署(前后端部署在不同的服务器)

  • 优点:将对静态资源的访问和对接口的访问进行分离,Tomcat服务器只负责数据服务的访问

2.3 集群与负载均衡

集群:多台服务器构成一个整体,集群中的某台服务器叫服务器节点.

负载均衡: 将对集群的并发请求按需求分配到不同的服务器节点上

 

 

 

  • 优点:提供并发能力、可用性

2.4 分布式

  • 基于redis实现 分布式锁

  • 分布式数据库mycat

  • redis集群

  • 数据库中间件

  • 消息中间件

2.5 微服务架构

 

  • 微服务架构:将原来在一个应用中开发的多个模块进行拆分,单独开发和部署

  • 保证可用性、性能

 

posted @ 2021-08-13 10:42  丨渍丨  阅读(101)  评论(0)    收藏  举报