redis的一些知识点

redis:

缓存还可以实现 熔断机制:当存储层挂掉了,可以将
                        请求打在缓存上,保证系统的
                        运行。

特点:数据类型丰富
      支持数据磁盘持久化存储
      支持主从
      支持分片

为什么Redis能这么快?
100000+QPS(QPS即query per second,每秒内查询的次数)
1.完全基于内存,绝大部分请求是纯粹的内存操作,执行效率搞
2.采用单线程,单线程也能处理高并发请求,像多核也可以启动多实例
 (这里的单线程,是只在处理网络请求的时候,是单线程的)

3.数据结构简单,对数据操作也简单 类似HashMap,查找,操作都是 O(1)

4.使用多路I/O复用模型,非阻塞IO

多路I/O复用模型
FD: File Descriptor, 文件描述符
    一个打开的文件用过唯一的描述符进行引用,该描述符
    是打开文件的元数据到文件本身的映射。

select 系统调用  (NIO)

Redis采用的I/O多路复用函数:epoll/kqueue/evport/select
1.根据操作系统不用选择不用的函数
2.优先选择时间复杂度为O(1)的I/O多路复用函数作为底层实现
3.以时间复杂度为O(n)的select作为保底
4.react设计模式监听I/O事件

说说你用过的Redis的数据类型
String;  使用:  set name "redis"   incr UserId 自增1
Hash:  使用:hmset lilei name "LiLei" age 26  ;hget lilei age; hset lilei age 28
List:  使用: lpush mylist aaa; lrang mylist 0 10(从左到右取出 0-10个数),lpop 
Set:   使用:sadd myset 1111;smembers myset;
Sorted Set: 使用: zadd myzset 3 abc (这里的3,是大小排序);zrangebyscore myzet 0 10

集合有求交集,并集的操作

高级:HyperLogLog,用于支持存储地理位置信息的Geo


使用keys对线上的业务的影响
KEYS pattern:查找所有符合给定模式pattern的key
  A.KEYS指令一次性返回所有匹配的KEY
  B.键的数据量过大会使服务卡顿

SCAN cursor [MATCH pattern] [COUNT count]
  A.基于游标的迭代器,需要基于上一次的游标延续之前的迭代过程
  B.以0作为游标(cursor)开始一次新的迭代,直到命令返回游标0完成一次遍历
  C.不保证每次执行都返回某个给定数量的元素,支持模糊查询
  D.一次返回的数量不可控,只能是大概率符合count参数


从海量Key里查询出某一固定前缀的Key
命令:dbsize  (redis中的key的数量)
      keys k1*  (找出以k1开头的key)
      (若数据量过大,会使卡住)

命令:scan 0(游标) match k1*(条件) count 10 (返回10条)
      scan 0 match k1* count 10
    返回值:1) “3213213213” (游标,当前访问到的位置)
            2) 1)“k1432432”
                2)"k1798879"
                3)"k1789789"  (返回结果,不一定是10个)
                
      scan 3213213213 match k1* count 10
可能会获取到重复的数据,剩下的就要在代码曾进行控制了


如何通过redis实现分布式锁
   分布式锁需要解决的问题
   1.互斥性
   2.安全性
   3.死锁
   4.容错
   命令:SETNX key value:如果key不存在,则创建并赋值
   时间复杂度:O(1)
   返回值:设置成功,返回1;设置失败,返回0
   若key 存在 则返回0(即失败)
   
   如何解决setnx长期有效的问题
   EXPIRE key seconds
   设置key的生存时间,当key过期时(生存时间为0),会被自动删除
    缺点:不是原子性操作
      
   在代码中这样使用:
   RedisService redisService = SpringUtils.getBean(RedisService.class);
   long status = redisService.setnx(key,"1");
   if(status == 1 ){
       //设置过期时间
       redisService.expire(key,expire);
       //执行独占资源逻辑
       something();
   }

   对上面方案的一个改进,
   SET key value [EX seconds] [PX milliseconds] [NX|XX]
   EX second:设置键的过期时间为second秒
   PX millisecond:设置键的过期时间为millisecond毫秒
   NX 只在键不存在时,才对键进行设置操作
   XX 只在键已存在时,才对键进行设置操作
   SET操作成功完成时,返回OK,否则返回nil
   
   可以将 value 设置成requestID,threadId,来标识被哪个占用了
   伪代码:
   RedisService redisService = SpringUtils.getBean(RedisService.class);
   String result = redisService.set(lockKey,threadId,SET_IF_NOT_EXIST,....,NX);
   
   if("OK".equals(result)){

       //执行独占资源逻辑
       something();
   } 
   
   
大量的key同时过期的注意事项
集中过期,由于清除大量的key很耗时,会出现短暂的卡顿现象
 解决方案:
     在设置key的过期时间的时候,给每个key加上随机值
     

如何使用Redis做异步队列
  使用List作为队列,RPUSH生产消息,LPOP消费消息
  缺点:没有等待队列里有值就直接消费
  弥补:可以通过在应用层引入sleep机制去调用lpop重试

  方法2:
  BLPOP key [key ...] timeout:阻塞直到队列有消息或者超时
  缺点:只能提供一个消费者消费
  
  方法3:
  pub/sub:主题订阅者模式
  pub:发布者   publish myTopic  "hello"
  sub:订阅者   subscribe  myTopic
  缺点:消息的发布是无状态的,无法保证可达
  
  
Redis如何做持久化 
方法一:
RDB(快照)持久化:保存某个时间点的全量数据快照
配置:redis.conf    vim redis.conf    /save(查找)
快照策略;
 save 900 1  900秒内有1条记录写入,就保存
 禁用rdb :
 save ""
 
 dump.rdb 就是数据保存的文件
 手动:
   save:阻塞Redis的服务器进程,直到RDB文件被创建完成
   bgsave:Fork出一个子进程来创建RDB文件,不阻塞服务器进程
  lastsave 上次执行save指令的时间
  
  可以使用代码隔一段时间调用bgsave,备份一下
  然后修改备份名称
  mv dump.rdb  dumpXXXXX.rdb
 
 自动化出发RDB持久化的方式
  根据redis.conf配置里的save m n 定时触发(用的是bgsave) 
  主从复制时,主节点自动触发
  执行Debug reload
  执行shutdown且没有开启AOF持久化
  
  copy-on-write 读共享


缺点;
   内存数据的全量同步,数据量大于I/O而严重影响性能
   可能会因为redis挂掉而丢失从当前至最近一次快照期间的数据


方法二:
AOF(Append-Only-File)持久化:保存写状态
  1.记录下除了查询以外的所有变更数据库状态的指令
  2.以append的形式追加保存到AOF文件(增量)
默认关闭
需要修改 redis.conf 中   appendonly no/yes
或者使用命令:config set appendonly yes

随着新增、修改命令不断增加,aof文件大小不断增加
日志重写解决AOF文件大小不断增加大小的问题
bgrewrite ,会触发,整合命令

redis启动时,如果有aof文件,就加载aof文件
没有的话,就加载rdb文件


RDB 和 AOF 的优缺点
RDB优点:全量数据快照,文件小,恢复快
RDB缺点:无法保存最近一次快照之后的数据
AOF优点;可读性高,适合保存增量数据,数据不易丢失
AOF缺点:文件体积大,恢复时间长

RDB-AOF混合持久化方式  4.0开始支持
AOF 前半段 是RDB的全量数据,后半段是redis对数据的操作
使用 BGSAVE 做镜像全量持久化,AOF做增量持久化
redis 重启是先加载rdb的数据,重构,再用aof 重现近期操作的命令


使用Pipeline的好处
pipeline 和 linux 的管道类似
redis基于请求/响应模型,单个请求处理需要一一应答
(若命令过多,会增大系统网络I/O的调用)
pipeline批量执行指令,节省多次IO往返的时间
(指令最好是互相没有依赖的)
有顺序依赖的指令建议分批发送

redis的同步机制
主从(写在主节点,读在从节点),
缺点:(主机节点挂了后,就不能进行写操作了)
redis Sentinel (分布式系统)
解决主从同步master宕机后,主从切换问题,
  监控:检查主从服务器是否运行正常
  提醒:通过API向管理员或者其他应用程序发送故障通知
  自动故障迁移:主从切换
哨兵:

redis 集群
  redis 集群原理:
  一致性哈希算法:对2^32取摸,将哈希值空间组织成虚拟的圆环。
  0 --2^32-1 


如何从海量数据里快速找到所需?
 分片:
   按照某种规则去划分数据,分散存储在多个节点上
   

猜你喜欢

转载自blog.csdn.net/wjxhhh123/article/details/87776704