有趣!Redis 之父与 CRC64 的神秘往事(上)

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 有趣!Redis 之父与 CRC64 的神秘往事(上)

大家好,我是 yes。

昨天表弟说有个学妹问他 Redis 为什么要用 CRC16(key) mod 16384 来计算 key 所处槽的位置,我想这 CRC 一般都是用来校验的,通过多项式转换成二进制再通过模2除法得到余数,这里用来做个 Hash 函数好像用的也没啥毛病(对于CRC不太了解的同学可以先去查查)。


于是我就去查,看看 Redis 的作者 antirez 有没有相关的介绍,这一查就查到了一位叫 mattsta 的老哥的 14 年写的文章,这老哥的文章可太有意思了,他认为 Redis 现在实现的 CRC 算法太简陋了,他有能提升 4 倍性能的增强版 CRC 算法 - CRCSpeed,因此他写了这篇文章进行了一波分析。


看完之后我马上去看了我本地 5.0 版本的源码,发现 CRC 算法并没有采纳他的增强版,还是老的实现。我又去看了最新 6.0 的版本,发现 CRC-64 改成了 CRCSpeed 的实现,在2020年4月28号提交的,提交者是 antirez,这就让我越发的好奇了,这2014到2020跨度有点大啊,到底发生了啥?


image.png


然后我又去看 mattsta 的 Github ,他还是 Redis 的 Contributor,于是我追踪了整个事情发展的历史脉络,事情越来越有意思了。我已经迫不及待地想和大家一起再来看一遍这哥们的文章,过一遍这件事。

不过我先到感谢一下我的表弟,不然我都没机会看到这篇文章,来表弟给大家打个招呼!

“大家好!我是表弟”。 好了表弟你可以走了。

表弟骂骂咧咧的退出群聊:“工具人就是工具人”。

接下来我就要用我蹩脚的英语来翻译了,如有纰漏敬请指正。


Fancy CRCing You Here


这老哥文章标题就有那味儿! Fancy CRCing You Here,我还特意去找了我专八同学来翻译一下。


然后这老哥文章的第一句话就很为人着想。

image.png

Redis 的 CRC-64 的实现有很多人拷贝到他们的项目中使用,CRC-16 也有少量拷贝。这算法是能用啊,但是可以有更好的实现。

我看了下 Github 上有 2353 个项目用到了 Redis 的 CRC-64 实现,325 个项目用到了 Redis 的 CRC-16 实现。


image.png


简单翻一下就是:

  • Redis 决定忽略吞吐量和延迟方面的提高,因为他们更喜欢像1999年那样编码
  • 代价就是他们过时的传统设计慢了40倍。大家干得漂亮啊。(不知道这老哥是笔误还是故意把4倍在开头写成40倍的,我就揣测下:),那个超链接跳过去就是标注着 antirez 写的 CRC-64 的实现,粗暴直接,我很喜欢)。
  • ,如果现在有人写了一个代替 redis 和 memcached 的实现就好了啊。

然后老哥就开始放招。


What’s Wrong


他先说了下 CRC 本质上是无法并行的,因为下一次迭代的值取决于前一次迭代。然后又指出了 Redis 中的哪几个地方使用到 CRC。


image.png

CRC-64 用在了三个地方:

  • 在跨实例迁移键时添加校验和,(并验证上述校验和)
  • 为 RDB 输出添加一个校验和,用于复制和持久化(是可选项,可通过配置禁用,因为性能低)
  • 用于内存测试

CRC-16 用在了一个地方:

  • 作为集群中分配集群槽的键的散列函数

mattsta 接着放招:


image.png


简单翻译下:这 Redis 的实现极其简单(这个 extremely 单词我很是喜欢)。就是一个简单的查表法,然后循环一个字节一个字节比过去,时间复杂度是O(N)。

马上这位老哥就抛出如何做才好。


What’s Better


image.png

简单翻译下:我在网上乱翻了一番,想看看其他人是如何实现 CRC-64 的。但是大部分是拷贝 Redis 的(哎,恨其不争)。

然后 mattsta 发现了 stackoverflow 有个叫 Mark 的哥们自己写了个高速版 CRC-64 实现,他将 Mark 的实现和 Redis 的实现进行了对比,发现 Mark 的版本比 Redis 版本快了400% ,分别是1.6 GB/s 和400 MB/s。


image.png

原谅我的孤陋寡闻,我一直以为 pretty 和 girl 比较配,原来还能用来和 awful搭,我学到了,嗯。pretty f...。

然后 mattsta 说我们不能直接用 Mark 的实现,但是我们可以看看是Mark 的实现。


What’s Improved


mattsta 先展示了下 Redis 的实现,就是每个字节循环操作,然后查表。


image.png

image.png

image.png

于是这位老哥找到了灵感,他要自己实现一个和 Redis 匹配的 CRC 算法。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
3月前
|
存储 NoSQL 算法
Redis HyperLogLog 是什么?这些场景使用它,让我枪出如龙,一笑破苍穹
Redis HyperLogLog 是什么?这些场景使用它,让我枪出如龙,一笑破苍穹
56 0
|
1月前
|
人工智能 监控 NoSQL
【万字长文 一文搞定】Redis:从新手村到大师殿堂的奥德赛之旅 9种实现分布式锁的全技术指南
【万字长文 一文搞定】Redis:从新手村到大师殿堂的奥德赛之旅 9种实现分布式锁的全技术指南
83 4
|
1月前
|
NoSQL Redis 数据库
【怒怼大厂面试官】听说你精通Redis?说说Redis持久化
咳咳咳,看你简历写了精通Redis,那我就随便问问。主要有RDB持久化、AOF持久化。是这样,Redis服务器会维护一个AOF重写缓冲区,该缓冲区会在子进程创建新AOF文件期间,记录服务器执行的所有写命令。
55 1
【怒怼大厂面试官】听说你精通Redis?说说Redis持久化
|
5月前
|
NoSQL 算法 Java
Redis魔法:点燃分布式锁的奇妙实现
Redis魔法:点燃分布式锁的奇妙实现
300 0
|
存储 NoSQL 算法
|
存储 运维 Kubernetes
分布式锁实战-偶遇 etcd 后就想抛弃 Redis ?
分布式锁实战-偶遇 etcd 后就想抛弃 Redis ?
569 0
分布式锁实战-偶遇 etcd 后就想抛弃 Redis ?
|
存储 NoSQL 算法
万字详解Redis技术
Redis(Remote Dictionary Server)是一个开源的使用 ANSI C 标准(c语言)编写、支持网络、可基于内存亦可持久化、Key-Value 类型的非关系型数据库,并提供多种语言的 API. 本文干活满满~~~
万字详解Redis技术
|
存储 缓存 NoSQL
走进 Redis,让你重新认识 redis。绝不是表面
说到Redis我们不禁的会联想到:缓存。提到缓存我们要聊的就有很多了。