作者:何永康,腾讯 CSIG 后台研发工程师 。
导语 | redis 大家用的不少,但是我们大多数人可能都只是关注业务本身,对于底层的细节则经常忽略,久而久之,对个人的成长帮助甚少 。本文为大家总结了关于 Redis 常见用法的进阶指南,希望帮助大家加深对这门技术的理解 。
一、Redis基础数据结构1. String
Redis 里的字符串是动态字符串,会根据实际情况动态调整 。类似于 Go 里面的切片-slice,如果长度不够则自动扩容 。至于如何扩容,方法大致如下:当 length 小于 1M 的时候,扩容规则将目前的字符串翻倍;如果 length 大于 1M 的话,则每次只会扩容 1M,直到达到 512M 。
文章插图
2. List
Redis 里的 List 是一个链表,由于链表本身插入和删除比较块,但是查询的效率比较低,所以常常被用做异步队列 。Redis 里的 List 设计非常牛,当数据量比较小的时候,数据结构是压缩链表,而当数据量比较多的时候就成为了快速链表 。
可运用的场景:在业务中异步队列使用 rpush/lpush 操作队列,使用 lpop 和 rpop 出队列,具体结构如下图所示:
文章插图
3. Set
Redis 中的 set 是一个无序 Map,由于 Go 中没有 set 结构,所以这里只能类比 JAVA 中的 HashSet 概念 。Redis 的 set 底层也是一个 Map 结构,不同于 Java 的是:alue 是一个 NULL 。由于 set 的特性,它可以用于去重逻辑,这一点在 Java 中也经常使用 。
可运用场景:活动抽奖去重 。
4. Hash
Redis 中的字典类型大家不陌生,也许其他语言都有这种结构(Python,Java,Go),hash 的扩容 rehash 过程和 Go 里面的设计颇有类似,也就是维护了两个 hash 结构,如果需要扩容的时候,就把新的数据写入新字典中,然后后端起一个线程来逐步迁移,总体上来说就是采用了空间换时间的思想 。
可运用场景:记录业务中的不同用户/不同商品/不同场景的信息:如某个用户的名称,或者用户的历史行为 。
文章插图
5. Zset
Redis 中的 zset 是一个比较特殊的数据结构(跳跃列表),也就是我们了解到的跳表,底层由于 set 的特性保证了 value 唯一,同时也给了 value 一个得分,所谓的有序其实就是根据这个得分来排序 。至于跳跃表如何插入,其实内部采用了一个随机策略:
L0:100%-L2:50%-L3:25%-....Ln:(n-1)value/2% 。
可运用场景:榜单,总榜,热榜 。
文章插图
二、Redis 进阶使用1. 布隆过滤器
Redis 在 4.0 以后支持布隆过滤(准确的来说是支持了布隆过滤器的插件),给 Redis 提供了强大的去重功能 。在业务中,我们可能需要查询数据库判断历史数据是否存在,如果数据库的并发能力有限,这个时候我们可以采用 Redis 的 set 做去重 。如果缓存的数据过大,这个时候就需要遍历所有缓存数据,另外如果我们的历史数据缓存写不下了,终究要去查询数据库,这个时候就可以使用布隆过滤器 。
当然布隆过滤器精确度不是 100% 准确(如果对数据准确度要求很高的话,这里不建议使用),因为对于存在的数据也许这个值不一定存在,当然如果不存在,那肯定 100% 不存在了 。
(1)命令使用
bf.add #添加元素bf.exists #判断元素是否存在bf.madd #批量添加bf.mexists #批量判断是否存在
(2)原理
文章插图
布隆过滤的组成可以当作一个位数组和几个计算结果比较均匀的 hash 函数,每次添加 key 的时候,会把 key 通过多次 hash 来计算所得到的位置,如果当前位置不是 0 则表示存在 。可以看到,这样的计算存在一定误差,这也正是它的不准确性问题的由来 。
2. 分布式锁
大家对分布式锁也许也不会陌生,现在市面上主流的实现分布锁的技术有 ZK 和 Redis;下文为大家简单介绍一下 Redis 如何实现分布式锁 。
命令
setnx lock:mutex ture #加锁dellock:mutex #删除锁
实现分布式锁的核心就是:请求的时候 Set 这个 key,如果其他请求设置失败的时候,即拿不到锁 。但是存在一个问题:如果业务 panic 或者忘记调用 del 的话,就会产生死锁,这个时候大家很容易能想到:我们可以 expire 一个过期时间,这样就可以保证请求不会一直独占锁且无法释放锁的逻辑了 。
推荐阅读
- Redis在用户注册登录的妙用
- 如何快速排查发现redis的bigkey?4种方案一次性给到你
- MySQL高级进阶:关于InnoDB存储结构,一文深入分析讲解
- 火山引擎 Redis 云原生实践
- 一篇详解Redis -- 延时队列
- 招聘|求职避坑指南:如何甄别招聘信息
- Vue 转 React 指南,看这篇文章就够了
- 超薄Docker容器-减少Docker镜像大小的指南
- HttpClient高级进阶-SSL
- 软路由上手指南