阅读redis源代码的一些体会

最近在学习redis及阅读redis等程序的源码时,有一些收获,特记录到下面。

1.第一步,阅读源代码借助最好可以跟踪的工具去读,如sourceinsight。
我使用的是windows7环境,又因为是c程序,故使用sourceinsight,当然还有其他的方式,比如阅读java代码可以导入到eclipse。

2. 第二步,搭建可以启动该源程序的环境,并能启动成功。

根据最简单的配置,使用源码编译的方式,启动该程序。逐渐参考用户使用手册,修改配置文件进行测试,进而熟悉redis的使用。

3.第三步,阅读代码前先理清楚源码的数据结构、基本概念、算法。

   数据结构诸如字典、双向链表的实现;

   概念诸如aof、rdb、主从复制等
4. 第四步,使用debug模式启动程序,跑完整个流程。
  使用redis的debug模式,了解运行的流程,理清思路。

5. 第五步,使用单元测试对数据结构、算法、流程进行单元测试。

   使用cunit先进行数据结构的单元测试,再进行算法,然后是流程的测试。

   最后考虑根据模块进行测试。

增加一条:

 6、增加打印日志和画代码流程图。1)猜测你认为的代码流程走向,并在你认为走到的地方增加自己的打印信息,运行程序,看看是否可以达到预期。整个和调 试BUG时用到的原理一样,重要的一点是你要先判断哪个地方会调用,自己去主导代码。2)画代码流程图,根据你已经熟悉的流程,把代码流程图画下来,方便自己整理思路,也能预防阅读到后面忘记了前面的码。图形的表现会远大于文字,大部分人刚开始都不愿意去画,包括我,后来感觉还是很有必要的。


学习redis的相关资料:

1. 《Redis入门很简单》

2. 《Redis设计与实现》

这两本书都看完了,感觉挺好的,昨天有入手了一本《Redis实战》还没看,本想入手一本英文的,奈何比中文版贵了好几倍。

看完这些书并应用起来后,上面的第一、二、三步应该就没OK啦。

官网推荐的书(http://redis.io/documentation)如下:

Books

The following is a list of books covering Redis that are already published. Books are ordered by release date (newer books first).

The following books have Redis related content but are not specifically about Redis:

4.  第四步,在redis.conf中需要配置一下loglevel为debug,如下:

# Specify the server verbosity level.
# This can be one of:
# debug (a lot of information, useful for development/testing)
# verbose (many rarely useful info, but not a mess like the debug level)
# notice (moderately verbose, what you want in production probably)
# warning (only very important / critical messages are logged)
loglevel debug

# Specify the log file name. Also the empty string can be used to force
# Redis to log on the standard output. Note that if you use standard
# output for logging but daemonize, logs will be sent to /dev/null
logfile "./log/redis_log.txt"

5.  下载最新版本的redis(3.2.0)会在main.c里面看到比以往版本中多加了测试代码:

#ifdef REDIS_TEST
    if (argc == 3 && !strcasecmp(argv[1], "test")) {
        if (!strcasecmp(argv[2], "ziplist")) {
            return ziplistTest(argc, argv);
        } else if (!strcasecmp(argv[2], "quicklist")) {
            quicklistTest(argc, argv);
        } else if (!strcasecmp(argv[2], "intset")) {
            return intsetTest(argc, argv);
        } else if (!strcasecmp(argv[2], "zipmap")) {
            return zipmapTest(argc, argv);
        } else if (!strcasecmp(argv[2], "sha1test")) {
            return sha1Test(argc, argv);
        } else if (!strcasecmp(argv[2], "util")) {
            return utilTest(argc, argv);
        } else if (!strcasecmp(argv[2], "sds")) {
            return sdsTest(argc, argv);
        } else if (!strcasecmp(argv[2], "endianconv")) {
            return endianconvTest(argc, argv);
        } else if (!strcasecmp(argv[2], "crc64")) {
            return crc64Test(argc, argv);
        }

        return -1; /* test not found */
    }
#endif

如果需要测试以上的数据结果需要在makefile文件中,添加相关预编译:

FINAL_CFLAGS+= -DREDIS_TEST

至于如何使用cunit进行白盒测试,还不清楚。