48

阿里云技术专家仲肥:了解并使用Redis 4.0

 5 years ago
source link: http://www.10tiao.com/html/195/201806/2658357827/1.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

前言


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好了,我们来看下粉丝数:



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



小插曲:Redis 4.0扩展了slowlog的返回结果,展示了产生慢日志的客户端IP:PORT以便追本溯源。


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



可以看到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》

资源链接:

https://yq.aliyun.com/articles/205504


Lua脚本支持随机操作


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


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


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


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



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


脚本修改如下:



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



基于LFU的热点key发现机制


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


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

资源链接:

http://click.aliyun.com/m/1000004110/


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



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



MEMORY内存分析命令


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


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



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

资源链接:

http://click.aliyun.com/m/1000004111/


开始体验Redis 4.0


  • 点击这里查看Redis 4.0 Release Note

    资源链接:

    https://github.com/antirez/redis/blob/4.0-rc1/00-RELEASENOTES

  • 体验阿里云数据Redis 4.0版请猛击

    资源链接:

    http://click.aliyun.com/m/1000004112/



作者简介


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



end

新增16条设计规约!阿里巴巴Java开发手册(详尽版)开放下载!

阿里90后工程师利用ARM硬件特性开启安卓8终端“上帝模式”

国内首家!阿里云宣布全面提供IPv6服务

API管理工具Swagger介绍及Springfox原理分析

机器学习和数据科学领域必读的10本免费书籍

更多精彩


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK