Redis拓展及5.0新特性

Redis5.0新特性

1.Stream 特性

stream.png

概念:是一个新的强大的支持多播的可持久化的消息队列
组成:一个消息链表,将所有加入的消息都串起来,每个消息都有一个唯一的 ID 和对应的内容。消息是持久化的,Redis 重启后,内容还在。
每个Stream可以挂多个消费组,每隔消费组都有一个last_delivered_id在Stream数组之上移动,表示消费者已经移动到那条信息了。
消息Id:timestampInMillis-sequence 是时间戳+随机数。可由服务器自己生产也可自己指定。
命令:xadd 增加消息 xdel:删除消息 xrange:获取消息列表,自动过滤已经删除的消息,xleng:获取消息长度,del:删除stream.

##one 是key  *标识服务器自动产生Id(573786170148-0) 后边跟很多的key和value 
172.31.123.211:9999> xadd one * name zhh v 20
"1573786170148-0"
172.31.123.211:9999> xadd one * name zhh v 21
"1573786212867-0"
172.31.123.211:9999> xadd one * name zhh v 22
"1573786223915-0"
172.31.123.211:9999> xlen one
(integer) 3
##- 标识最小值,+标识最大值 列出所有的消息
172.31.123.211:9999> XRANGE one - +  
1) 1) "1573786170148-0"
   2) 1) "name"
      2) "zhh"
      3) "v"
      4) "20"
2) 1) "1573786212867-0"
   2) 1) "name"
      2) "zhh"
      3) "v"
      4) "21"
3) 1) "1573786223915-0"
   2) 1) "name"
      2) "zhh"
      3) "v"
      4) "22"
##根据队列中的Id删除 xdel key  id
172.31.123.211:9999> XDEL one 1573786170148-0
(integer) 1
##获取队列长度 xlen key
172.31.123.211:9999> xlen one
(integer) 2

消费者独立消费:

##count 标识读取几条 而 streams one 0-0 标识 id要大于0-0
172.31.123.211:9999> xread count 1 streams one 0-0
1) 1) "one"
   2) 1) 1) "1573786212867-0"
         2) 1) "name"
            2) "zhh"
            3) "v"
            4) "21"
##注意这个与上述不同 加入了bock 0 标识阻塞读取 返回最新的消息 并且加入了 $ 标识 意思告诉streams 已经存储的最大ID作为最后一个ID 相当于linux 中的tail -f 
172.31.123.211:9999> xread count 1 block 0 streams one $

创建消费组

#xgroup create key groupName 0-0 表示Id大于0的消息
172.31.123.211:9999> XGROUP create one c1 0-0
OK
##获取消费者组信息
172.31.123.211:9999> xinfo groups one
1) 1) "name"
   2) "c1"
   3) "consumers"
   4) (integer) 0
   5) "pending"
   6) (integer) 0
   7) "last-delivered-id"
   8) "0-0"
###消费者组读取信息   其中符号">" 标识获取最新的 msg,及没有返回给其他消费者的消息。
XREADGROUP group c1 c count 1 streams one >  
##ack 一条信息
XACK codehole cg1 1527851486781-0

stream 在每个消费者结构中保存了正在消费的消息ID,每个消费者的ID组成了
PEL列表 ,如果消费者忘记确认消费,那么这个消费者的PEL内存会越来越大

stream如何保证消息不丢失
当客户端读取Stream消息时,Redis服务器返回给客户端时,如果客户端断开连接,消息就丢失了。但是消费者中的数据结构PEL列表保存了已经发送出去的消息ID,当客户端重新连接后,可以再次收到PEl中的消息ID。

Stream和pub/sub有什么区别

区别.png

Redis Stream 简介

Info指令

redis的info指令非常强大,可以显示的信息非常多,一般可以分为9大块
info server/clients/memory/persistence/stats/replication/cpu/cluster/KeySpace
1、Server 服务器运行的环境参数
2、Clients 客户端相关信息
3、Memory 服务器运行内存统计数据
4、Persistence 持久化信息
5、Stats 通用统计数据
6、Replication 主从复制相关信息
7、CPU CPU 使用情况
8、Cluster 集群信息
9、KeySpace 键值对统计数量信息

172.31.123.211:9999> info stats
# Stats 
total_connections_received:2
total_commands_processed:47
instantaneous_ops_per_sec:0
total_net_input_bytes:3101
total_net_output_bytes:25863
instantaneous_input_kbps:0.00
instantaneous_output_kbps:0.00
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
expired_stale_perc:0.00
expired_time_cap_reached_count:0
evicted_keys:0
keyspace_hits:42
keyspace_misses:0
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:889
migrate_cached_sockets:0
slave_expires_tracked_keys:0
active_defrag_hits:0
active_defrag_misses:0
active_defrag_key_hits:0
active_defrag_key_misses:0
172.31.123.211:9999> info persistence
# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1573795747
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:0
rdb_current_bgsave_time_sec:-1
rdb_last_cow_size:4481024
aof_enabled:0
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
aof_last_cow_size:0

主要介绍几个 比较重要的 操作:
1.查看复制积压缓冲区大小

127.0.0.1:6379[2]> info replication
# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576 #这个就是复制缓冲区的大小
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

这个参数非常重要,当主从同步的时候,从库因为网络问题断开连接,主库修改的命令都会写入到这个缓冲区,当从库恢复的时候,从库可以从缓冲区恢复主库修改的命令。
缓冲区是环形的,上面有提到过,后面来的执行会覆盖前面的指令,如果从库断开时间过长,或者缓冲区设置的大小过小,都会导致数据丢失的情况。那么这个时候就需要全量同步了,全量同步是十分耗费网络资源和CPU的。
多个从库共享一个缓冲区。
2.查看redis占用多大内存

[hanghang.zhang@bogon bin]$ redis-cli -p 6379 -a 02903954-2df7-11e6-89f6-b7c698d5ea2d info memory|grep human
used_memory_human:509.97M  内存分配器从操作系统分配的内存
used_memory_rss_human:579.53M  
used_memory_peak_human:550.11M
total_system_memory_human:31.03G 操作系统总内存大小
used_memory_lua_human:37.00K 脚本引擎占用的大小
maxmemory_human:0B

Redis做分布式锁所面临的问题。

我们介绍过redis分布式锁,一条指令就可以完成加锁操作,不过在集群的环境下,他是有缺陷的,并不是绝对安全。
比如在 Sentinel 集群中,主节点挂掉时,从节点会取而代之,客户端上却并没有明显感知。
原先第一个客户端在主节点中申请成功了一把锁,但是这把锁还没有来得及同步到从节点,主节点突然挂掉了。然后从节点变成了主节点,这个新的节点内部没有这个锁,所以当另一个客户端过来请求加锁时,立即就批准了。
这样就会导致系统中同样一把锁被两个客户端同时持有。
而且这种情况仅仅发生在主从failOver的情况下,才会产生。
解决这个问题,Redis出现了readLock算法,加锁时,他会想半数借点发送set(key,value,nx=True,ex=xxx)指令,只有过半节点才会成功。释放锁,需要向所有节点发送del指令。

Redis过期key

因为Redis是单线程的,在过期key删除的同时,也会占用线程的时间,如果删除的过多,会导致线上服务卡顿。
Redis将过期的key放在一个独立的字典里面,定时扫面这个数据字典,来删除到期的key。或者使用惰性策略来删除过期的 key,所谓惰性策略就是在客户端访问这个 key 的时候,redis 对 key 的过期时间进行检查,如果过期
了就立即删除。定时删除是集中处理,惰性删除是零散处理。
因为Redis是定时扫面过期key,如果有大批量key过期,会导致线上服务器卡顿,所以有大批量的 key 过期,要给过期时间设置一个随机范围,而不能全部在同一时间过期,

redis.expire(key,random.nexInt(86400)+exirpe);

在一些活动系统中,因为活动是一期一会,下一期活动举办时,前面几期的很多数据都可以丢弃了,所以需要给相关的活动数据设置一个过期时间,以减少不必要的 Redis 内存占用。

Redis惰性删除

如果一个key值过大,直接点用redis 的del指令 造成服务器卡顿,及为解决删除大key问题,redis在4.0版本以上加入了 unlink 指令

>unlink key

可以将整个 Redis 内存里面所有有效的数据想象成一棵大树。
当 unlink 指令发出时,它只是把大树中的一个树枝别断了,然后扔到旁边的火堆里焚烧 。树枝离开大树的一瞬间,它就再也无法被主线程中的其它指令访问到了,因为主线程只会沿着这颗大树来访问。

redis提供flushDb和flushAll 用来清空数据库,这也是极其缓慢的操作。也可以加入异步化,

>flushDb async / flushAll async

Redis4.0 为这些删除点也带来了异步删除机制,打开这些点需要额外的配置选项。
1、slave-lazy-flush 主从同步,快照同步时,从库接受完 rdb 文件后的 flush 操作
2、lazyfree-lazy-eviction 内存达到 maxmemory 时进行淘汰
3、lazyfree-lazy-expire key 过期的key进行删除时
4、lazyfree-lazy-server-del rename 指令删除 destKey

程序员.jpg
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355

推荐阅读更多精彩内容

  • NOSQL类型简介键值对:会使用到一个哈希表,表中有一个特定的键和一个指针指向特定的数据,如redis,volde...
    MicoCube阅读 3,981评论 2 27
  • 1.1 资料 ,最好的入门小册子,可以先于一切文档之前看,免费。 作者Antirez的博客,Antirez维护的R...
    JefferyLcm阅读 17,056评论 1 51
  • 五种数据结构简介 Redis是使用C编写的,内部实现了一个struct结构体redisObject对象,通过结构体...
    彦帧阅读 6,944评论 0 14
  • 原文链接:Redis实现消息队列的方案 Redis作为内存中的数据结构存储,常用作数据库、缓存和消息代理。它支持数...
    这个ID狠温柔阅读 101,240评论 2 28
  • 你说我太轴,你说我一跟你闹别扭就想回家,你说干嘛老不讲话 不是你提醒,都不知道自己这么讨厌 我说我年纪轻轻想太多,...
    你叫我婆婆阅读 214评论 0 0