linux上用gdb调试redis源码

最近为了对比传统分布式解决方案与区块链的解决方案的实际不同对比其不同和优缺点,便从redis的sentinel和cluster的解决方案入手来看,在查完官网和书中对redis模型的看基本描述后,其实最好的办法还是调试一下实际的代码,redis是用c实现,本地机器是windows的,又没有安装c的ide,且仅仅是调试用,所以就参考官网的调试的方法Redis debugging guide本着简单的方式来调试代码。
首先在windows上安装一个ubuntu的子系统,以后方便在这个系统上调试和部署其他linux的代码。如何安装子系统请自行百度。打开ubuntu的终端操作如下:

安装redis

先下载redis的源码并安装可直接参考官网: redis quickstart

wget http://download.redis.io/redis-stable.tar.gz
tar xvzf redis-stable.tar.gz
cd redis-stable
make
sudo make install
## 测试redis是否安装成功
redis-server
## 出现如下即已安装成功
7854:C 03 Jul 17:54:03.179 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
7854:C 03 Jul 17:54:03.179 # Redis version=4.0.10, bits=64, commit=00000000, modified=0, pid=7854, just started
7854:C 03 Jul 17:54:03.180 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
7854:M 03 Jul 17:54:03.183 * Increased maximum number of open files to 10032 (it was originally set to 1024).
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 4.0.10 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 7854
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

7854:M 03 Jul 17:54:03.192 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
7854:M 03 Jul 17:54:03.193 # Server initialized
7854:M 03 Jul 17:54:03.194 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
7854:M 03 Jul 17:54:03.198 * DB loaded from disk: 0.000 seconds
7854:M 03 Jul 17:54:03.219 * Ready to accept connections

安装gdb

sudo apt-get install  gdb

使用gdb debug redis源码

## 为了调试,在编译redis的源码的时候需要带上参数
make CFLAGS="-g -O0" 
## 如果之前已经编译过的话,可以删掉makefile文件重新编译即可。
## 执行如下命令
gdb redis-server
## 即可进入gdb的模式 如下:
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from redis-server...done.
(gdb)
## 先设置一个断点,并运行至该点断的位置,gdb支持断点到方法,如下:断点在main方法、并运行至该断点。
(gdb) b main
Breakpoint 1 at 0x433700: file server.c, line 3704.
(gdb) r
Starting program: /usr/local/bin/redis-server
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, main (argc=1, argv=0x7ffffffee1b8) at server.c:3704
3704    int main(int argc, char **argv) {
(gdb)

至此已经进入了debug的模式,并且现在的停留在server.c的main方法中,为了看的更方便可以执行如下命令进入多窗口模式可以边看源码边调试,还有一些其他命令的用法可以参考 Debugging with GDBgdb 调试利器

## 进入多窗口模式
 (gdb) layout src
## 出现如下图的界面
image.png
## 简单调试的基本用法
## 进入下一步next简写n
(gdb) n
## 进入方法里面 step,如下进入就是setproctitle.c中的spt_init方法里
(gdb) step
spt_init (argc=1, argv=0x7ffffffee1b8) at setproctitle.c:153
## 打印当前的一些变量值
(gdb) p argc
$1 = 1
## 跳出当前方法
(gdb) finish
## 当然还有很多更高级的用法,自行参考官网,或者使用help命令查看一些说明,在或者google
(gdb) help

到此就是整个简单使用gdb来调试redis源码的基本流程。下面我们就用gdb来试着调试一下sentinel模式将运行的代码。

准备调试redis配置文件和启动命令

搭建sentinel的模型,目标3个sentinel,1个主服务器,2个从服务器。
详细搭建教程可参考:Replication

配置1主2从

## 配置一主两从的结构 创建一个配置文件夹
$ sudo mkdir /svr/redis_config
$ sudo cp /svr/redis-stable/redis.conf /svr/redis_config/redis_6379.conf
$ cd /svr/redis_config
$ sudo cp redis_6379.conf redis_6380.conf
$ sudo cp redis_6379.conf redis_6381.conf
$ sudo vim redis_6379.conf
$ sudo vim redis_6380.conf
$ sudo vim redis_6381.conf

分别修改端口号和pid文件名和后台进程启动

## 以6380文件为例,修改如下几个值
port 6380
daemonize yes
slaveof 127.0.0.1 6379
pidfile /var/run/redis_6380.pid
## 保存之后退出,依次修改另一个文件,启动redis实例
$ sudo redis-server /svr/redis_config/redis_6379.conf
$ sudo redis-server /svr/redis_config/redis_6380.conf
$ sudo redis-server /svr/redis_config/redis_6381.conf
## 另外一种配置的从库方法就是客户端连上从库之后发送如下命令即可
$ sudo redis-cli -p 6380
127.0.0.1:6380> slaveof 127.0.0.1 6379

至此redis的主从就搭建好了.可以通过redis-cli连接发送info命令查看服务器状态信息

搭建三个sentinel

更多的配置细节参考:官网topic之sentinel

## 拷贝sentinel文件
$ sudo cp /svr/redis-stable/sentinel.conf /svr/redis_config/sentinel_26379.conf
$ sudo cp /svr/redis-stable/sentinel.conf /svr/redis_config/sentinel_26380.conf
$ sudo cp /svr/redis-stable/sentinel.conf /svr/redis_config/sentinel_26381.conf
$ sudo vim /svr/redis_config/sentinel_26379.conf
## 同样修改配置如下内容,以26380为例,其中dir为工作路径,请在启动前请确保此文件夹存在。
## sentinel的myid在三个文件中请一定要配置不同,因为这个值代表这个sentinel的runid。配置监听的主服务器和选票的数量。
port 26380
daemonize yes
dir "/svr/redis_config/sentinel_26380/tmp"
sentinel myid 672268275d7a8a9809acaa83ecc4f63dce39fc5a
sentinel monitor mymaster 127.0.0.1 6379 2
## 保存退出后启动应用
$ sudo redis-sentinel /svr/redis_config/sentinel_26379.conf
$ sudo redis-sentinel /svr/redis_config/sentinel_26380.conf
$ sudo redis-sentinel /svr/redis_config/sentinel_26381.conf
## 也可以用sentinel模式,如:
$ sudo redis-server sentinel_26381.conf --sentinel

至此三个sentinel已经搭建好了

## 客户端连接查看sentinel是否已经相互连接,使用info命令便可以看到详细信息
$ sudo redis-cli -p 26379
127.0.0.1:26379> info
# Server
redis_version:4.0.10
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:564e829c2a2c36f6
redis_mode:sentinel
os:Linux 4.4.0-17134-Microsoft x86_64
arch_bits:64
multiplexing_api:epoll
atomicvar_api:atomic-builtin
gcc_version:5.4.0
process_id:8472
run_id:3d6ee9716c852c234bdb61515372046396adb0b9
tcp_port:26379
uptime_in_seconds:35
uptime_in_days:0
hz:11
lru_clock:3907301
executable:/svr/redis_config/redis-sentinel
config_file:/svr/redis_config/sentinel_26379.conf

# Clients
connected_clients:3
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0

# CPU
used_cpu_sys:0.02
used_cpu_user:0.02
used_cpu_sys_children:0.00
used_cpu_user_children:0.00

# Stats
total_connections_received:3
total_commands_processed:75
instantaneous_ops_per_sec:1
total_net_input_bytes:3904
total_net_output_bytes:484
instantaneous_input_kbps:0.02
instantaneous_output_kbps:0.01
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
expired_stale_perc:0.00
expired_time_cap_reached_count:0
evicted_keys:0
keyspace_hits:0
keyspace_misses:0
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:0
migrate_cached_sockets:0
slave_expires_tracked_keys:0
active_defrag_hits:0
active_defrag_misses:0
active_defrag_key_hits:0
active_defrag_key_misses:0

# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=127.0.0.1:6379,slaves=2,sentinels=3

从最后一行我们可以看到整个网络架构已经建立好了。

## 也可以用如下命令查看sentinels 信息
127.0.0.1:26379> sentinel sentinels mymaster
1)  1) "name"
    2) "672268275d7a8a9809acaa83ecc4f63dce39fc5b"
    3) "ip"
    4) "127.0.0.1"
    5) "port"
    6) "26381"
    7) "runid"
    8) "672268275d7a8a9809acaa83ecc4f63dce39fc5b"
    9) "flags"
   10) "sentinel"
   11) "link-pending-commands"
   12) "0"
   13) "link-refcount"
   14) "1"
   15) "last-ping-sent"
   16) "0"
   17) "last-ok-ping-reply"
   18) "488"
   19) "last-ping-reply"
   20) "488"
   21) "down-after-milliseconds"
   22) "30000"
   23) "last-hello-message"
   24) "259"
   25) "voted-leader"
   26) "?"
   27) "voted-leader-epoch"
   28) "0"
2)  1) "name"
    2) "672268275d7a8a9809acaa83ecc4f63dce39fc5a"
    3) "ip"
    4) "127.0.0.1"
    5) "port"
    6) "26380"
    7) "runid"
    8) "672268275d7a8a9809acaa83ecc4f63dce39fc5a"
    9) "flags"
   10) "sentinel"
   11) "link-pending-commands"
   12) "0"
   13) "link-refcount"
   14) "1"
   15) "last-ping-sent"
   16) "0"
   17) "last-ok-ping-reply"
   18) "488"
   19) "last-ping-reply"
   20) "488"
   21) "down-after-milliseconds"
   22) "30000"
   23) "last-hello-message"
   24) "562"
   25) "voted-leader"
   26) "?"
   27) "voted-leader-epoch"
   28) "0"

调试sentinel的相关代码

结合前面简单的调试和sentinel的配置文件,我们可以使用gdb来启动一个sentinel从main方法来开始调试。

## 先关掉一个sentinel
$ ps -aux|grep redis
root      7995  0.0  0.0  45636  2356 ?        Ssl  Jul03   0:01 redis-server 127.0.0.1:6379
root      8046  0.0  0.0  45636  2096 ?        Ssl  Jul03   0:00 redis-server 127.0.0.1:6380
root      8054  0.0  0.0  45636  2092 ?        Ssl  Jul03   0:01 redis-server 127.0.0.1:6381
jane-zh+  8267  0.0  0.0  16224   260 tty3     S    Jul03   0:00 redis-cli -p 26379
root      8286  0.0  0.0  14892   576 tty4     S    Jul03   0:00 sudo redis-cli -p 26380
root      8287  0.0  0.0  16224   256 tty4     S    Jul03   0:00 redis-cli -p 26380
root      8472  0.0  0.0  43588  2800 ?        Ssl  00:05   0:00 redis-sentinel *:26379 [sentinel]
root      8478  0.0  0.0  43588  2704 ?        Ssl  00:05   0:00 redis-sentinel *:26380 [sentinel]
root      8484  0.0  0.0  43588  2720 ?        Ssl  00:05   0:00 redis-sentinel *:26381 [sentinel]
root      8488  0.0  0.0  14656  2120 tty2     S    00:05   0:00 sudo redis-cli -p 26379
root      8489  0.0  0.0  16224  1284 tty2     S    00:05   0:00 redis-cli -p 26379
jane-zh+  8491  0.0  0.0  12892  1112 tty5     S    00:18   0:00 grep --color=auto redis
$ sudo kill -9 8472
## 使用gdb启动redis-sentinel命令
$ sudo gdb redis-sentinel
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from redis-sentinel...done.
(gdb) b main
Breakpoint 1 at 0x433700: file server.c, line 3704.
(gdb) r /svr/redis_config/sentinel_26379.conf
Starting program: /usr/local/bin/redis-sentinel /svr/redis_config/sentinel_26379.conf
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, main (argc=2, argv=0x7ffffffee698) at server.c:3704
3704    int main(int argc, char **argv) {
(gdb) layout src

至此便可以愉快的开始从头调试sentinel的代码,调试步骤依然像前面简单介绍的一样。下篇便是开始总结redis的sentinel。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容

  • 前言 Redis是一个高性能的key-value数据库,现时越来越多企业与应用使用Redis作为缓存服务器。楼主是...
    liangzzz阅读 4,194评论 9 152
  • http://blog.51cto.com/mxlmgl/2065789 redis-server说明 服务器A:...
    SkTj阅读 2,088评论 0 5
  • 超强、超详细Redis入门教程 转载2017年03月04日 16:20:02 16916 转载自: http://...
    邵云涛阅读 17,323评论 3 313
  • 文章已经放到github上 ,如果对您有帮助 请给个star[https://github.com/qqxuanl...
    尼尔君阅读 2,220评论 0 22
  • 这是一个异世界,这里分为两个,门派,一是人派,没有灵力,平凡但充满智慧,他们生活得安逸,祥和,另外一个是灵派,...
    星辰蚕少阅读 672评论 0 0