• 4-------扩展篇


    Stream

    一个强大的支持多播的可持久化消息队列。

    消息链表,将所有加入的信息都串起来,每个消息都有一个唯一的ID和对应的内容。消息是持久化的,重启内容还在的。

    每个Stream都有唯一的名称,他就是Redis的key,在首次使用xdd指令追加消息时自动创建

    1. 每个Stream都挂有多个消费组,每个消费组都有一个last_delivered_id在stream数组之上往前移动,表示当前消费组已经在消费到了哪条信息。
    2. 每个消费组都有一个Stream内唯一的名称,消费组不会自动创建,它需要单独的指令xgroup_create进行创建,并且初始化last_delivered_id变量。
    3. 同意消费组可以挂接多个消费者,这些消费者之间是竞争关系,任意一个消费者读取了信息都会移动游标
    4. 消费者内部有一个pending_ids,记录当前已经被客户端读取,但是还没有ack的消息。如果客户端没有ack,这个变量里面的消息ID就会越来越来多。

    消息ID

    消息ID形式:时间戳+本次时间内的第几条

    1-2:当前时间为1毫秒,这个消息时这个时刻产生的第二条消息

    消息内容

    消息内容就是键值对,形如hash结构的键值对

    增删改查

    xadd:向Stream中追加消息

    xdel:从Stream中删除消息

    xrange:获取Stream中的消息列表

    xlen:获取Stream消息长度

    del:删除整个Stream消息列表中的所有信息

    独立消费

    客户端:xread block 1000 count 1 streams name

    阻塞1s,如果有消息的话,就出来,没有的话就没用。

    创建消费组

    xgroup create name cg1 0-0;;;;没什么用的

    消费

    Stream消息太多怎么办

    使用xadd指令删除掉。

    消息如果忘记ack会怎样

    不怎么样,PEL会越来越长

    PEL如何避免丢失

    反正保存在了PEL当中,等连接上了再传就行了。

    Stream的高可用

    可以在分布式集群中使用

    分区Partition

    Stream没有分区的能力,只能多创建几个Stream,并把不同的数据发送到不同的Stream上供消费

    小结

    感觉应该不会用到的,所以觉得没用

    Info指令

    获得Redis内部的一些参数

    Server  服务器运行的环境参数
    Clients 客户端相关信息
    Memory 服务器运行内存统计数据
    Persistence 持久化信息
    Stats 通用统计数据
    Replication 主从复制相关信息
    CPU CPU使用情况
    Cluster 集群信息
    KeySpace 键值对统计数据信息

     

     

     

     

     

     

    再谈分布式锁

    当主节点挂掉了,从节点取而代之;但是有可能客户端申请成功了一把锁,但是此时主节点挂了,但是从节点也没有同步这个加锁的操作就升级成了主节点,那么这个时候就出问题了。另外一个客户端申请了锁,问题更大了,鸠占鹊巢

    Redlock算法

    需要导入redlock模块

    加锁时:客户端向过半节点发送加锁请求,请求成功了就加锁成功;释放锁的时候,需要向所有节点发送del指令。

    Redlock使用场景

    但是很慢哦

    过期策略

    Redis所有的数据结构都可以设置过期时间,时间一到,就会被自动删除。

    Redis是单线程的,收割的时间也会占用线程的处理时间,如果收割的太过频繁,会导致卡顿

    过期的key的集合

    Redis会将每个设置了过期时间的key放入一个独立的字典中,之后会定时遍历这个字典来删除到期的key。

    除了定时删除,它还会使用惰性策略来删除过期的key。所谓惰性删除就是在客户端访问这个key的时候,Redis对key的过期时间进行检查,如果过期了就立即删除。

    定时删除:集中处理

    惰性删除:零散处理

    定时扫描策略

    默认每秒10次扫描

    1. 从过期字典中随机选出20个key
    2. 删除这20个key中已经过期的key
    3. 过期的key超过了1/4,那就重复一次

    为了保证扫描不会出现循环过度,导致线程卡死的现象,算法还增加了扫描时间的上限,默认不会超过25ms

    当客户端请求到来时,服务器如果正好进入过期扫描状态,客户端的请求将会等待至少25ms才会处理,如果客户端将超时时间设置得比较短,那么就会出现很多超时关闭。

    所以业务开发人员一定要注意过期时间,如果有大批量得key过期,要给过期时间设置一个随机范围,而不能全部在同一时间过期。

    通过随机化过期时间总是很好得解决定期扫描过期得事情。

    从节点的过期策略

    从节点不会过期扫描,从节点对过期得处理是被动得。主节点在key到期时,会在AOF文件中增加一条del指令。然后从节点删除过期得节点。但是可能导致主节点中删除了,但是从节点中没有删除得现象。

    优胜劣汰-LRU

    当Redis内存超出了物理内存限制时,内存得数据会开始和磁盘产生频繁得交换(Swap)。但是redis是不能存在数据交换操作得

    所以当超内存之后会有以下机中方法:

    1. noeviction:不会继续服务写请求
    2. volatile-lru:尝试淘汰设置了过期时间得key,最少使用得key优先被淘汰
    3. volatile-ttl:比较设置过过期时间得key,但是比较每个key剩余得生命ttl,来选择淘汰得key
    4. volatile-random:跟上面得一样,但是淘汰得是过期得key集合
    5. allkeys-lru:对所有得key来一次lru
    6. allkeys-random:淘汰得随机得key

    总结:volatile-xxx只针对带过期时间得key进行淘汰,allkeys-xxx策略会对所有得key进行淘汰。

    LRU算法

    实现LRU算法除了需要key/value字典外,还需要附加一个链表。

    当空间满的时候,会踢掉链表尾部的元素。当字典的某个元素被访问,就会被移动到表头。所以链表的元素排列就是元素最近被访问的时间顺序。

    近似LRU算法

    Redis使用的是一种近似的LRU算法,跟Lru算法有一点不一样。之所以不适用Lru算法,是因为需要大量的额外空间。

    Redis给每个key增加一个额外的小字段,这个字段的长度是24个bit,也就是最后一个被访问的时间戳。

    RedisLru算法采用的是懒惰处理,随机采样5个key,然后淘汰最旧的key,如果淘汰后还是超内存,就继续采样淘汰。

    是否只对设置了过期的key进行LRU算法,取决于maxmemory-policy设置。

    删除的东西会放在淘汰池中,慢慢删除。

    懒惰删除

    后台删除线程

    Redis为什么使用懒惰删除

    删除大对象还是很慢的,所以要异步丢给后台删除线程处理

    flush

    flushdb、flushall都是很慢的操作,因为是直接删除完,但是可以flushall async丢给后台线程慢慢处理

    异步队列

    一头再往里面加删除的数据,一边在删除,所以这个队列需要线程安全的

    AOF Sync

    也是开辟一个线程,进行实时的同步写日志文件

    更多异步删除点

    redis4.0给下面的指令也是带来的异步删除

    slave-lazy-flush:从节点接受完rdb文件后的flush操作

    lazyfree-lazy-eviction:内存达到maxmemory时进行删除

    lazyfree-lazy-expire key:过期删除

    lazyfree-lazy-server-del rename:指令删除destKey

    Jedis

    Redis开源客户端

    Jedispool,jedis连接池

    需要使用try-with-resource语句来保护jedis对象,一定要释放连接啊。

    重试

    没有重试机制,需要自己写重试。

    保护Redis

    指令安全

    1. redis可以设置rename-command指令,给一些危险的指令重命名。

    端口安全

    不要使redis服务器的网址暴露在外面

    Lua脚本安全

    让redis以普通用户的方式启动,防止黑客拿到root权限

    SSL代理

    redis不支持SSL,意味着客户端和服务器之间的交互数据不能直接暴露在公网上传输。但是可以使用SSL代理。

    使用spipedSSH对通道进行二次加密

    Redis安全通信

    使用ssl给数据加密

    spiped原理

    在客户端和服务器端都开启一个spiped的线程

    一个加密和解密的过程

    spiped进程监听一个端口接收数据,并且使用这个端口发送数据;客户端先将数据发送到piped上进行加密,然后传输到服务器端,服务器端进行解密,发送到服务器上。

    spiped

    可以同时支持多个客户端连接的数据转发工作,还可以通过参数来限定允许的最大客户端连接数,但是对于服务器spiped,它不能同时支持多个服务器之间的转发。需要为每一个server节点启动一个spiped进程来代收消息。

  • 相关阅读:
    用户和用户组管理
    浏览器从输入URL到页面加载显示完成全过程解析
    easyui form提交和formdata提交记录,查看FormData对象内部的值
    Hybrid App中原生页面 VS H5页面(分享)
    ui-router .state参数配置
    利用webpack手动构建vue工程
    使用json对象要注意的地方
    js中使用0 “” null undefined {}需要注意
    已知宽高和未知宽高的div块的水平垂直居中
    jquery easyui datagrid 空白条处理 自适应宽高 格式化函数formmater 初始化时会报错 cannot read property 'width'||'length' of null|undefined
  • 原文地址:https://www.cnblogs.com/sicheng-li/p/13299376.html
Copyright © 2020-2023  润新知