Aldebaran

人生最棒的感觉,就是你做到别人说你做不到的事。

0%

Redis源码编译

三田寺円

什么是Redis

Redis是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库。

根据月度排行网站DB-Engines.com的数据显示,Redis是最流行的键值对存储数据库。

Redis 和 Memcached的区别

  • redis与memcached相比,比仅支持简单的key-value数据类型,同时还提供list,set,zset,hash等数据结构的存储;
  • redis支持数据的备份,即master-slave模式的数据备份;
  • redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用等等;

准备工作

这里以redis-4.0.6为例子

编译

$ cd /usr/local/src
$ wget http://download.redis.io/releases/redis-4.0.6.tar.gz
$ tar xvzf redis-4.0.6.tar.gz && cd redis-4.0.6
$ sudo make PREFIX=/usr/local/redis-4.0.6 install
$ ln -s /usr/local/redis-4.0.6 /usr/local/redis

初始化环境

$ sudo mkdir /usr/local/redis/etc
$ sudo mkdir -pv /data/{redis_data,redis_log}
$ sudo mkdir -pv /data/redis_data/6379

拷贝并编辑启动脚本

# Copy the init script that you'll find in the Redis distribution under the utils directory into /etc/init.d. We suggest calling it with the name of the port where you are running this instance of Redis. For example:
$ sudo cp -pv utils/redis_init_script /etc/init.d/redis_6379

# Edit the init script.
$ sudo sed -i 's#\/usr\/local\/bin#\/usr\/local\/redis/bin#g' /etc/init.d/redis_6379
$ sudo sed -i 's#\/etc\/redis\/\${REDISPORT}#\/usr\/local\/redis\/etc\/redis\-\${REDISPORT}#' /etc/init.d/redis_6379

拷贝配置文件

# Edit the configuration.
$ cp redis.conf /usr/local/redis/etc/redis-6379.conf
$ cp sentinel.conf /usr/local/redis/etc/sentinel.conf.old
$ vim /usr/local/redis/etc/redis-6379.conf

Redis配置

这里列出我目前在用的redis配置(未开启持久化,如果是单实例建议开启持久化)

daemonize yes
pidfile /tmp/redis-6379.pid
port 6379
bind 127.0.0.1
timeout 0
loglevel notice
logfile /data/redis_log/redis-6379.log
databases 32
#save 900 1
save 300 100
#save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump-6379.rdb
dir /data/redis_data/6379
maxclients 10000
maxmemory 10GB
#maxmemory-policy allkeys-lru

appendonly no
#appendfsync everysec
#appendfilename appendonly-6379.aof
no-appendfsync-on-rewrite yes
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 1024

#rename-command FLUSHALL a140fc02d524015429941cc15f59e41cbflushall
#rename-command FLUSHDB  b240fc02d524025429941cc15f59e42cb8flushdb
#rename-command CONFIG   c340fc02d524035429941cc15f59e43cb9bconfig
#rename-command SLAVEOF  d340fc02d524035429941cc15f59e43c9bslaveof

## Special encoding of small aggregate data types
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64

activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60

slave-serve-stale-data yes
slave-read-only no
slave-priority 100

可能遇到的问题

这里列出编译过程中可以遇到的问题。

  1. net.core.somaxconn

    9689:M 27 Dec 16:18:43.815 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.

    处理:

    修改/etc/sysctl.conf文件,增加一行 net.core.somaxconn= 1024;
    然后执行命令:sysctl -p

    原因:

    net.core.somaxconn是linux中的一个kernel参数,表示socket监听(listen)的backlog上限。backlog是socket的监听队列,当一个请求(request)尚未被处理或建立时,他会进入backlog。而socket server可以一次性处理backlog中的所有请求,处理后的请求不再位于监听队列中。当server处理请求较慢,以至于监听队列被填满后,新来的请求会被拒绝。
    
    所以说net.core.somaxconn限制了接收新 TCP 连接侦听队列的大小。
    对于一个经常处理新连接的高负载 web服务环境来说,默认的 128 太小了。大多数环境这个值建议增加到 1024 或者更多。
  2. overcommit_memory

    9689:M 27 Dec 16:18:43.815 # 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.

    处理:

    $ echo 1 > /proc/sys/vm/

    overcommit_memory参数说明:

    设置内存分配策略(可选,根据服务器的实际情况进行设置)
    /proc/sys/vm/overcommit_memory
    可选值:0、1、2。
    0, 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。
    1, 表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
    2, 表示内核允许分配超过所有物理内存和交换空间总和的内存
    注意:redis在dump数据的时候,会fork出一个子进程,理论上child进程所占用的内存和parent是一样的,比如parent占用的内存为8G,这个时候也要同样分配8G的内存给child,如果内存无法负担,往往会造成redis服务器的down机或者IO负载过高,效率下降。所以这里比较优化的内存分配策略应该设置为 1(表示内核允许分配所有的物理内存,而不管当前的内存状态如何)。
  3. transparent_hugepage

    9689:M 27 Dec 16:18:43.816 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.

    处理:

    $ echo never > /sys/kernel/mm/transparent_hugepage/enabled

Redis参考文档

Redis官网

Configuration Reference

Redis Documentation

Redis之Sentinel高可用安装部署