摘要: 社区最新GA版本Redis 4.0推出已近一年,阿里云数据库Redis 4.0版也上线近半年,之前关于Redis 4.0的系列文章从源码实现来分析这些新功能,本文旨在从用户角度出发,让Redis的用户能够快速了解并使用Redis 4.0带来的福利。

前言

Redis作为时下最火爆的NoSQL数据库以性能强悍、数据结构丰富著称,同时其成长的脚步也从未停止,自诞生伊始已经历多次蜕变不断推出新功能。

社区最新GA版本Redis 4.0推出已近一年,阿里云数据库Redis 4.0版也上线近半年,之前关于Redis 4.0的系列文章从源码实现来分析这些新功能,本文旨在从用户角度出发,让Redis的用户能够快速了解并使用Redis 4.0带来的福利。

Lazyfree

大key删除的问题想必很多用户都遇到过,Redis除string外还支持list、set、hash和sorted set等复杂数据结构,这些数据结构丰富了Redis的用法,但是如果使用不当造成单key体积过大的话就会引起一些问题。

举个简单的例子,假如某社交网站有一个大V,有上百万的粉丝,我们可以用set集合类型的数据结构来存储他的粉丝ID,存储粉丝集合的key叫做funs好了,我们来看下粉丝数:

127.0.0.1:6379> SCARD funs
(integer) 6320505

的确是大V,有600多万的粉丝,但是很不幸的有一天这个大V注销了,这时就要删除他的信息,我们用DEL命令来删除这个key:

127.0.0.1:6379> DEL funs
(integer) 1
(3.11s)
127.0.0.1:6379> slowlog get
1) 1) (integer) 42) (integer) 15281699233) (integer) 31048124) 1) "DEL"2) "funs"5) "127.0.0.1:48398"6) ""
  • 小插曲:Redis 4.0扩展了slowlog的返回结果,展示了产生慢日志的客户端IP:PORT以便追本溯源。

可以看到删除这个动作居然耗时3秒多,也就意味着这3秒内Redis无法执行其他命令,这对于线上业务来讲是有伤害的,那么如何避免删除大key时的阻塞问题呢?Redis 4.0推出了Lazyfree这一功能,使用UNLINK命令来删除大key,主线程只负责把key从数据库中"摘除",真正的释放动作放在了BIO后台线程去做,我们来看下效果:

127.0.0.1:6379> UNLINK funs
(integer) 1
(3.11s)
127.0.0.1:6379> slowlog get
(empty list or set)

可以看到UNLINK执行很快没有产生slowlog。

Lazyfree一共有3个命令:

  1. UNLINK:异步删除key
  2. FLUSHDB ASYNC:异步清空当前DB
  3. FLUSHALL ASYNC:异步清空所有DB

以及4个配置项:

  1. lazyfree-lazy-expire:异步删除过期key
  2. lazyfree-lazy-eviction:异步淘汰key
  3. lazyfree-lazy-server-del:隐式删除时采取异步删除,比如rename a b,若b存在则需删除b
  4. slave-lazy-flush:全量同步时,slave异步清空所有DB

对于源码实现有兴趣的读者可以阅读《Redis 4.0之Lazyfree》。

Lua脚本支持随机操作

Redis内嵌了Lua环境来支持用户扩展功能,但是出于数据一致性考虑,要求脚本必须是纯函数的形式,也就是说对于一段Lua脚本给定相同的参数,重复执行其结果都是相同的。

为什么要有这个限制呢?原因是Redis不仅仅是单机版的内存数据库,它还支持主从复制和持久化,执行过的Lua脚本会复制给slave以及持久化到磁盘,如果重复执行得到结果不同,那么就会出现内存、磁盘、slave之间的数据不一致,在failover或者重启之后造成数据错乱影响业务。

还是以具体例子来看,假设有这么一段Lua脚本,目的很简单就是想记录下当前时间:

local now = redis.call('time')[1]redis.call('set','now',now)return redis.call('get','now')

这里使用了Redis的TIME命令来获取时间戳,然后存储到名为now的key中,但是其执行时会报错:

$redis-cli --eval escript
(error) ERR Error running script (call to f_cfba5ec6a699dad183456f19d1099d8dabfdb80c):
@user_script:3: @user_script: 3: Write commands not allowed after non deterministic commands.
Call redis.replicate_commands() at the start of your script in order to switch to single commands replication mode.

错误提示也很明显,如果执行过非确定性命令(也就是TIME,因为时间是随机的),Redis就不允许执行写命令,以此来保证数据一致性。那如何才能实现随机写入呢?刚才的错误提示也给出了答案,使用redis.replicate_commands(),在执行redis.replicate_commands()之后,Redis就不再是把整个Lua脚本同步给slave和持久化,而是把脚本中调用Redis的写命令直接去做复制,那么slave和持久化也可以得到确定的结果。

脚本修改如下:

redis.replicate_commands()local now = redis.call('time')[1]redis.call('set','now',now)return redis.call('get','now')

再执行就可以实现随机写入了:

$redis-cli --eval escript
"1528191578"$redis-cli --eval escript
"1528191804"

基于LFU的热点key发现机制

LFU是Redis 4.0新增的一类内存逐出策略,提供了更精确的内存淘汰算法,其本质是记录了一段时间内key的访问频率,同时也带来了额外的福利就是热点key的发现。

LFU简单来讲就是用0-255来表示key的访问频率,值越大说明访问频率越高,并且这里对频率的计数采用的是基于对数的概率增长,LFU为255可以代表100W次的访问,关于LFU的实现有兴趣的读者可以参考《Redis 4.0之基于LFU的热点key发现机制》。

使用OBJECT FREQ命令即可获取指定key的访问频率,不过需要首先把内存逐出策略设置为allkeys-lfu或者volatile-lfu:

127.0.0.1:6379> config get maxmemory-policy
1) "maxmemory-policy"
2) "noeviction"
127.0.0.1:6379> object freq counter:000000006889
(error) ERR An LFU maxmemory policy is not selected, access frequency not tracked. Please note that when switching between policies at runtime LRU and LFU data will take some time to adjust.127.0.0.1:6379> config set maxmemory-policy allkeys-lfu
OK
127.0.0.1:6379> object freq counter:000000006889
(integer) 3

使用scan命令遍历所有key,再通过OBJECT FREQ获取访问频率并排序,即可得到热点key。为了方便用户使用,Redis自带的客户端redis-cli也提供了热点key发现功能,执行redis-cli时加上--hotkeys选项即可,示例如下:

$./redis-cli --hotkeys# Scanning the entire keyspace to find hot keys as well as
# average sizes per key type.  You can use -i 0.1 to sleep 0.1 sec
# per 100 SCAN commands (not usually needed).[00.00%] Hot key 'counter:000000000002' found so far with counter 87
[00.00%] Hot key 'key:000000000001' found so far with counter 254
[00.00%] Hot key 'mylist' found so far with counter 107
[00.00%] Hot key 'key:000000000000' found so far with counter 254
[45.45%] Hot key 'counter:000000000001' found so far with counter 87
[45.45%] Hot key 'key:000000000002' found so far with counter 254
[45.45%] Hot key 'myset' found so far with counter 64
[45.45%] Hot key 'counter:000000000000' found so far with counter 93-------- summary -------Sampled 22 keys in the keyspace!
hot key found with counter: 254    keyname: key:000000000001
hot key found with counter: 254    keyname: key:000000000000
hot key found with counter: 254    keyname: key:000000000002
hot key found with counter: 107    keyname: mylist
hot key found with counter: 93    keyname: counter:000000000000
hot key found with counter: 87    keyname: counter:000000000002
hot key found with counter: 87    keyname: counter:000000000001
hot key found with counter: 64    keyname: myset

MEMORY内存分析命令

分析内存可以优化Redis的使用方式,全新的MEMORY命令可以帮助用户来实现这一操作。

MEMORY命令一共有5个子命令,可以通过MEMORY HELP来查看:

127.0.0.1:6379> memory help
1) "MEMORY DOCTOR                        - Outputs memory problems report"
2) "MEMORY USAGE <key> [SAMPLES <count>] - Estimate memory usage of key"
3) "MEMORY STATS                         - Show memory usage details"
4) "MEMORY PURGE                         - Ask the allocator to release memory"
5) "MEMORY MALLOC-STATS                  - Show allocator internal stats"

关于各个子命令的详细使用方式可以参考《Redis 4.0之MEMORY命令详解》。

开始体验Redis 4.0

  • 点击这里查看Redis 4.0 Release Note
  • 体验阿里云数据Redis 4.0版请猛击

作者简介

赵钊,花名仲肥,阿里云技术专家,专注于阿里云数据库Redis版的开发工作,活跃于Redis开源社区,致力让开发者使用最好的云数据库服务。

原文链接
本文为云栖社区原创内容,未经允许不得转载。

Why Redis 4.0?相关推荐

  1. 在CentOS 6.3 64bit上安装redis 3.0.3

    1.下载源码并安装 安装Unix的Tcl工具, 测试redis时需要用到 yum install tcl 去redis官网 http://redis.io/download/下载源码, 目前最新版本是 ...

  2. 带你100% 地了解 Redis 6.0 的客户端缓存

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 近日 Redis 6.0.0 GA 版本发布,这是 Redis 历 ...

  3. 大神级教程!300分钟撸一个基于Redis 6.0 版本的高并发架构

    刚好原先公司搞职位调整,我不太满意,赶上这波金三银四的面试浪潮,干了也有5年的后端开发了,不是大神也是有实战经验的,我就自信满满地去面了几家大厂,结果就遇到... 面试官这夺命连环12问,谁顶得住? ...

  4. 2W 字详解 Redis 6.0 集群环境搭建实践

    原文链接:https://www.cnblogs.com/hueyxu/p/13884800.html 本文是Redis集群学习的实践总结(基于Redis 6.0+),详细介绍逐步搭建Redis集群环 ...

  5. Redis 6.0 新特性-多线程连环13问!

    来自:码大叔 导读:支持多线程的Redis6.0版本于2020-05-02终于发布了,为什么Redis忽然要支持多线程?如何开启多线程?开启后性能提升效果如何?线程数量该如何设置?开启多线程后会不会有 ...

  6. Linux/ubuntu 安装 redis 4.0报错解决:redis-server.service: Can't open PID file /var/run/redis/redis-server.

    此文首发于我的个人博客:Linux/ubuntu 安装 redis 4.0报错解决:redis-server.service: Can't open PID file /var/run/redis/r ...

  7. Redis 4.0.X版本reshard出现错误的解决办法

    原文链接:https://my.oschina.net/juluking/blog/1606222 原作者的版本是Redis 4.0.6,我的版本是4.0.8,所以猜测是否所有4.0.x版本都有此问题 ...

  8. Q新闻丨MongoDB更换开源协议;Redis 5.0、Angular 7.0发布

    编辑 | 小智 本周要闻: 特斯拉在上海购买厂房用地:Google Play 在欧洲将变成付费服务:Redis 5.0 正式发布:Angular 7.0.0 发布:GitHub 发布史上最大更新:PH ...

  9. Redis 5.0.3默认配置启动报错解决方法

    Redis 5.0.3默认配置启动报错解决方法 参考文章: (1)Redis 5.0.3默认配置启动报错解决方法 (2)https://www.cnblogs.com/miclesvic/p/1031 ...

  10. 重磅消息:Redis 6.0.0 稳定版发布

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | https://www.sohu.com/a/ ...

最新文章

  1. 用P3P header解决IE下iframe跨域访问时候session丢失的问题
  2. python中类的嵌套_python类的嵌套
  3. Web API之service worker
  4. React 16 Jest单元测试 之 Jest工具
  5. LeetCode面试刷题技巧-二分查找算法代码思路解析
  6. ubuntu linux下面运行《暗黑破坏神2》和英雄无敌3-死亡阴影
  7. YII2操作mongodb笔记(转)
  8. 小度智能音响拆解 芯片_拆解报告:小度人工智能音箱1S
  9. reduce 数据倾斜_Spark(四十)数据倾斜解决方案之将reduce join转换
  10. 语义分割之VOC2012、Cityscapes数据集介绍
  11. 中小企业上云如何选择及操作
  12. 阿里云云计算 12 对象存储 Object Storage Service OSS 的概念
  13. HashMap底层原理源码分析
  14. html上下两个箭头符号怎么打出来,上下两个半箭头符号怎么打啊?高手进来看下,有图示的!...
  15. Android利用SpannableStringBuilder设置TextView中部分文字的颜色...
  16. 面包板入门电子制作 学习笔记8
  17. 关键路径 详解 (前置知识:拓扑排序)
  18. html5倒车游戏,html5制作转盘游戏
  19. 谨以此文,献给昨晚为志玲姐姐通宵奋战的广大程序猿兄弟们!
  20. 硬件知识:DP接口和HDMI接口对比,看完你就懂了

热门文章

  1. .idea文件夹是做什么的_33 个 IDEA 最牛配置,写代码太爽了!
  2. python动态页面元素爬取_爬取动态网页python+Web kit
  3. 打开fiddler后打不开网页_如何通过fiddler的导入导出功能,保存一份分类管理的请求报文...
  4. java 并发_Java并发防范机制
  5. php比例算法,图片比例转换算法
  6. mysql group by 规则_mysql 的group by 满足的规则要求:
  7. Apache java文件比对,Java Apache Commons的字符串比较
  8. 新春拜年被亲戚问到成绩时,怎么办?学会这6法,情商上涨蹭蹭蹭!
  9. 争分夺秒!一大批高校正在加紧扩建......
  10. 12岁女孩自学成才考上亚利桑那大学,博士母亲的家庭教育造就「天才少女」...