01、Redis 源码解析 - 为什么要读 Redis 源码

Redis的学习历程

第一次接触Redis是在校招的时候,为了准备面试,在网上搜些乱七八糟的“八股文”,发现Redis的出现频率非常高,什么Redis为什么这么快、Redis的应用场景、Redis怎么做持久化等等,当时看的云里雾里,便买了黄健宏老师的《Redis设计与实现》来啃,对书里的内容只能理解个大概,知道Redis是个高性能、高可用的大型分布式缓存系统,不过应付校招面试已经足够了。

工作之后逐步开始使用Redis,不过对Redis的使用比较浅显,只是简单的Get/Set,同时大厂的基础设施比较完善,使用时不必关心Redis集群的搭建、运维,开发人员最多关注下对Redis性能影响较大的一些大Key、热Key、fork等操作,校招面试时问的Redis知识很少用到,这里要吐槽下“面试造火箭、工作拧螺丝”。工作之余,便开始自主研究起Redis,网上的资料繁多,而且大多千篇一律,讲解的不够深入,索性就直接开始阅读Redis源码,所谓源码面前,了无秘密,我认为对于个人编码能力第一次质的提升是阅读了两个系统的源码,一个是Redis,一个是Nginx(虽然这个系列讲得是存储,还是强烈推荐Nginx源码,真正读完,会对网络编程、模块化设计有非常深的领悟)。把Redis源码阅读了2遍之后,算是真正入了门,知道Redis是如何设计的,但是只是“知道Redis是如何设计的”,对于Redis为什么这么设计,还有没有其他更好的设计方法仍然一知半解。

后面公司做私有云,开始接触Redis二次开发、深度定制,在运维Redis集群过程中积累了大量的问题排查经验,同时也给Redis社区提了几次commit,对Redis的理解更深了一步,比如:都在说Redis快,单机14W的QPS,相比于同定位的MemCache来说,真的快吗?单线程模型(暂不考虑异步删key)在编码上确实是简单了,但是真的是最优的线程模型吗,会有什么限制?对于当前动辄几十核的服务器,Redis要怎么部署才能达到较高的资源利用率?一般来说,由于fork的影响,单节点都不会太大(不超过20G),如何突破这个限制?去中心化的Gossip协议在大集群下如何解决消息太多问题?master宕机时,选举出来的follower一定能够保证数据不丢失吗?等等。这些都是在深度阅读Redis源码之后思考的问题,也是Redis社区讨论的重点之一。

阅读Redis源码能带来什么

从我的经验看来,阅读Redis源码至少可以带来以下几点好处:

1、掌握Redis实现细节
功利一点的说,Redis基本是面试的必问基础内容,熟悉Redis源码之后,应付面试游刃有余;同时对Redsi细节的掌握能够帮助我们更好的使用Redis,在排查Redis性能、故障问题时,快速高效的找到排查思路。

2、学习Redis编码规范和编程技巧
Redis作为一个纯C开发的分布式缓存系统,代码的稳定性和健壮性早已经过生产环境充分验证,是一份优秀的C语言学习素材。

3、了解一个分布式系统的设计方法
Redis以10w行的代码量构造了一个工业级的分布式系统,短小精悍,虽然Redis不能算是严格意义上的分布式存储系统,但是处处体现了分布式存储系统的设计思想。数据持久化中的快照RDB采用了最简单的copy on write中的fork,除了fork,还有哪些copy on write方法,同时这种COW快照与MVCC快照(例如Mysql、LevelDB)又有哪些不同;主从同步中,failover机制与分布式一致性协议Raft非常相似;集群模式下的分片机制是分布式系统中提高可扩展性的最常用手段,与Dynamo也很相似;Redis与Cassandra都是采用去中心化的Gossip协议,两者有何异同,谁的可扩展性更好。
在这个专栏中,准备结合自己多年Redis开发经验,通过梳理源码的方式学习Redis的编程技巧和设计思想,希望能给大家的工作中带来收获。