redis配置文件详解及实现主从同步切换

redis复制

Redis复制很简单易用,它通过配置允许slave Redis Servers或者Master Servers的复制品。接下来有几个关于redis复制的非常重要特性:

  • 一个Master可以有多个Slaves。

  • Slaves能过接口其他slave的链接,除了可以接受同一个master下面slaves的链接以外,还可以接受同一个结构图中的其他slaves的链接。

  • redis复制是在master段是非阻塞的,这就意味着master在同一个或多个slave端执行同步的时候还可以接受查询。

  • 复制在slave端也是非阻塞的,假设你在redis.conf中配置redis这个功能,当slave在执行的新的同步时,它仍可以用旧的数据信息来提供查询,否则,你可以配置当redis slaves去master失去联系是,slave会给发送一个客户端错误。

  • 为了有多个slaves可以做只读查询,复制可以重复2次,甚至多次,具有可扩展性(例如:slaves对话与重复的排序操作,有多份数据冗余就相对简单了)。

  • 通过复制可以避免master全量写硬盘的消耗:只要配置 master 的配置文件redis.conf来“避免保存”(注释掉所有”save”命令),然后连接一个用来持久化数据的slave即可。但是这样要确保masters 不会自动重启。

原理:redis复制是怎么进行工作

  1. 如果设置了一个slave,不管是在第一次链接还是重新链接master的时候,slave会发送一个同步命令 然后master开始后台保存,收集所有对修改数据的命令。当后台保存完成,master会将这个数据文件传送到slave,然后保存在磁盘,加载到内存中;master接着发送收集到的所有的修改数据的命令,这好比一个流命令,是redis协议本身来实现的。

  2. 当master和slave因一些故障宕机时,slaves会自动的重链,如果master收到多个slave的同步请求,master会执行一个后台保存,以确保所有的slaves都是正常的。 当master和slave能够维持链接,就会有一个完整的同步进行。

配置redis主从

  • 配置主从同步是很简单的,仅仅在slave的配置文件中增加类似下面这行的内容:

slaveof 192.168.1.1 6379

你可以更换master的ip地址或地址,或者,你可以使用slaveof命令,master就会启动和slave的同步。

  • 设置slave到master的认证

如果master需要通过密码登陆,那就需要配置slave在进行所有同步操作也要使用到密码。 在一个运行的实例上尝试,使用 redis-cli :

config set masterauth <password>

你也可以设置永久的。在配置文件中增加:

masterauth <password>

具体细节看下面。

安装redis

下载安装:

wget  	
tar  zxvf redis-2.8.2.tar.gz
cd 	redis-2.8.2
make  	PREFIX=/usr/local/redis  install
cp     	redis.conf     /usr/local/redis/

配置环境变量:

echo "export PATH=$PATH:/usr/local/redis/bin/" >>/etc/profile
source /etc/profile

Nohup启动和停止redis服务的命令

# 后台启动
nohup /usr/local/redis/bin/redis-server /usr/local/redis/redis.conf &
# 同时也可以修改配置文件实现后台启动,只需将daemonize no改为yes即可
# 停止
/usr/local/redis/bin/redis-cli  -p  6379 shutdown

安装php-redis连接驱动

要确保PHP能够连接Redis缓存服务器,需添加PHP Redis扩展程序,也即是添加PHP安ext扩展模块:

wget  https://github.com/phpredis/phpredis/archive/3.1.2.tar.gz 
tar   xzf  3.1.2.tar.gz
# 必须运行下面的命令,编译PHP扩展的工具,主要是根据系统信息生成对应的configure文件
/usr/local/php/bin/phpize cd   phpredis-3.1.2/
./configure --with-php-config=/usr/local/php/bin/php-config --enable-redis
make
make install

修改vim /usr/local/php/etc/php.ini配置文件,添加redis.so模块,代码如下

extension_dir = /usr/local/php5/lib/php/extensions/no-debug-zts-20090626" //这句不用添加也行
extension=redis.so

重启apache,检查phpinfo的测试页面,是否支持redis模块即可。

LAMP+REDIS进行缓存测试:

登陆web服务器,修改Discuz PHP网站发布/usr/local/apache2/htdcos目录全局配置文件config_global.php,将redis服务器名称改为redisIP地址即可。

vim /usr/local/apache2/htdocs/config/config_global.php 
// --------------------------  CONFIG MEMORY  --------------------------- //
$_config['memory']['prefix'] = 'Ybxjgy_';
$_config['memory']['redis']['server'] = '192.168.1.21';
$_config['memory']['redis']['port'] = 6379;

通过浏览器访问Apache PHP论坛网站,同时登陆Redis服务器,执行命令redis-cli进入Redis命令行,运行命令KEYS *,如图12-11所示,存在以IOKLAN开头的key,则证明Redis成功缓存LAMP+Discuz网站信息数据。

redis-cli 
redis 127.0.0.1:6379> keys *
1) "Ybxjgy_common_member_field_forum_1"
2) "Ybxjgy_forumlinks"
3) "Ybxjgy_threadtable_info"

同时你也可以测试缓存是否生效,在论坛注册用户,因为是第一次注册,用户名会写入到mysql数据库中,同时也会写入到redis缓存,然后你将mysql数据库中的该用户删除,发现依然可以使用之前注册的用户可以正常登陆网站,则说明缓存生效。这里就不再列出命令。

redis主从实战

准备两台redis服务器。

192.168.1.21 redis-master 192.168.1.24 redis-slave

开启主服务器的后台运行,将配置文件中 daemonize no改为daemonize yes

开启从服务器的后台运行,及设置slaveof的IP和端口:

vim redis.conf
port 6379daemonize yes
slaveof 192.168.1.21 6379

重启redis主库和从库,测试主从同步。在主redis是上创建key values.然后在从redis上进行查询:

主库:

redis-cli redis 
127.0.0.1:6379> set jj www.jiajie.meOKredis 
127.0.0.1:6379> set jia www.jiajie.comOKredis 
127.0.0.1:6379> get jj"www.jiajie.me"redis 
127.0.0.1:6379> get jia"www.jiajie.com"

从库:

redis-cli 
127.0.0.1:6379> get jj"
127.0.0.1:6379> get jia"
127.0.0.1:6379> set jie www.jiajie.org
(error) READONLY You can't write against a read only slave.

发现主从同步成功。从服务器只能进行读操作。

主从切换

停止redis主服务器:

[root@localhost redis]# redis-cli -p 6379 shutdown
[root@localhost redis]# redis-cli -p 6379 
Could not connect to Redis at 127.0.0.1:6379: Connection refused
not connected>

将redis从服务改为主:

#也可以直接在数据库命令行中输入slaveof no one
[root@localhost redis]# redis-cli -p 6379 slaveof NO ONEOK
[root@localhost redis]# redis-cli 127.0.0.1:6379> set jiajie www.jiajie.org
OK127.0.0.1:6379> get jiajie"www.jiajie.org"

发现从redis可以写数据了。

假如原来的主redis恢复正常啦。要重新切换回去。

1). 将现在的主redis数据进行保存。

[root@localhost redis]# redis-cli 
127.0.0.1:6379> get jiajie"www.jiajie.org"
127.0.0.1:6379> save
OK
127.0.0.1:6379> get jiajie"www.jiajie.org"

2).将现在的主redis的dump.rdb文件拷贝到原来的主dump.rdb目录下面

[root@localhost redis]# scp /data/redis/dump.rdb 192.168.1.21:/data/redis/dump.rdb

3).启动原来的主redis

[root@localhost ~]# /usr/local/redis/bin/redis-server /usr/local/redis/redis.conf

4).将原来的从依然切换成从

[root@localhost redis]# redis-cli -p 6379 slaveof 192.168.1.21 6379
OK
[root@localhost redis]# redis-cli 
127.0.0.1:6379> get jiajie"www.jiajie.org"

这时你依然可以读取刚才从库写入的数据,如果不能读取则切换失败。

redis 配置文件详解

# daemonize no  Linux Shell终端运行redis,改为yes即后台运行Redis服务;
daemonize yes
# 当运行多个 redis 服务时,需要指定不同的pid文件和端口
pidfile /var/run/redis_6379.pid
# 指定redis运行的端口,默认是 6379
port 6379
# 在高并发的环境中,为避免慢客户端的连接问题,需要设置一个高速后台日志
tcp-backlog 511
# 指定redis只接收来自于该 IP 地址的请求,如果不进行设置,那么将处理所有请求
# bind 192.168.1.100 10.0.0.1
# bind 127.0.0.1#设置客户端连接时的超时时间,单位为秒。当客户端在这段时间内没有发出任何指令,那么关闭该连接;
timeout 0
# 在Linux 上,指定值(秒)用于发送 ACKs 的时间。注意关闭连接需要双倍的时间。默认为 0 。
tcp-keepalive 0
# Redis总共支持四个日志级别: debug 、 verbose 、 notice 、 warning ,默认为 verbose
# debug     记录很多信息,用于开发和测试# varbose   有用的信息,不像 debug 会记录那么多
# notice    普通的 verbose ,常用于生产环境
# warning   只有非常重要或者严重的信息会记录到日志
loglevel notice
#配置 log 文件地址#默认值为 stdout ,标准输出,若后台模式会输出到 /dev/null 。
logfile /var/log/redis/redis.log
#可用数据库数#默认值为16 ,默认数据库为0,数据库范围在 0- ( database-1 )之间
databases 16
#数据写入磁盘快照设置#保存数据到磁盘,格式如下 :
#save <seconds> <changes>
#指出在多长时间内,有多少次更新操作,就将数据同步到数据文件 rdb 。
#相当于条件触发抓取快照,这个可以多个条件配合
#比如默认配置文件中的设置,就设置了三个条件#save 900 1  900 秒内至少有 1 个 key 被改变
#save 300 10  300 秒内至少有 300 个 key 被改变
#save 60 10000  60 秒内至少有 10000 个 key 被改变
# save 900 1# save 300 10# save 60 10000#  后台存储错误停止写。
stop-writes-on-bgsave-error yes
#  存储至本地数据库时(持久化到 rdb 文件)是否压缩数据,默认为 yes
rdbcompression yes
#  本地持久化数据库文件名,默认值为 dump.rdb
dbfilename dump.rdb
#  工作目录
#  数据库镜像备份的文件放置的路径。
#  这里的路径跟文件名要分开配置是因为 redis 在进行备份时,先会将当前数据库的状态写入到一个临时文件中,
#   等备份完成,再把该该临时文件替换为上面所指定的文件,而这里的临时文件和上面所配置的备份文件都会放在
#   这个指定的路径当中。
# AOF 文件也会存放在这个目录下面
#  注意这里必须制定一个目录而不是文件
dir /var/lib/redis/
################################# 复制 ################################## 
 主从复制 . 设置该数据库为其他数据库的从数据库 .
#  设置当本机为 slav 服务时,设置 master 服务的 IP 地址及端口,在 Redis 启动时,它会自动从 master 进行数据同步
# slaveof <masterip><masterport>
#  当 master 服务设置了密码保护时 ( 用 requirepass 制定的密码 )
# slave 服务连接 master 的密码# masterauth <master-password>
#  当从库同主机失去连接或者复制正在进行,从机库有两种运行方式:
# 1)  如果 slave-serve-stale-data 设置为 yes( 默认设置 ) ,从库会继续响应客户端的请求
# 2)  如果 slave-serve-stale-data 是指为 no ,出去 INFO 和 SLAVOF 命令之外的任何请求都会返回一个
#     错误 "SYNC with master in progress"slave-serve-stale-data yes
#  配置 slave 实例是否接受写。写 slave 对存储短暂数据(在同 master 数据同步后可以很容易地被删除)是有用的,
#  但未配置的情况下,客户端写可能会发送问题。
#  从 Redis2.6 后,默认 slave 为 read-onlyslaveread-only yes
#  从库会按照一个时间间隔向主库发送 PINGs. 可以通过 repl-ping-slave-period 设置这个时间间隔,默认是 10 秒
# repl-ping-slave-period 10# repl-timeout  设置主库批量数据传输时间或者 ping 回复时间间隔,默认值是 60 秒
#  一定要确保 repl-timeout 大于 repl-ping-slave-period
# repl-timeout 6
#  在 slave socket 的 SYNC 后禁用 TCP_NODELAY
#  如果选择“ yes ” ,Redis 将使用一个较小的数字 TCP 数据包和更少的带宽将数据发送到 slave , 
#  但是这可能导致数据发送到 slave 端会有延迟 , 如果是 Linux kernel 的默认配置,会达到 40 毫秒 .
#  如果选择 "no" ,则发送数据到 slave 端的延迟会降低,但将使用更多的带宽用于复制 .
repl-disable-tcp-nodelay no
#  设置复制的后台日志大小。
#  复制的后台日志越大, slave 断开连接及后来可能执行部分复制花的时间就越长。
#  后台日志在至少有一个 slave 连接时,仅仅分配一次。
# repl-backlog-size 1mb
#  在 master 不再连接 slave 后,后台日志将被释放。下面的配置定义从最后一个 slave 断开连接后需要释放的时间(秒)。
# 0 意味着从不释放后台日志
# repl-backlog-ttl 3600
#  如果 master 不能再正常工作,那么会在多个 slave 中,选择优先值最小的一个 slave 提升为 master ,
#  优先值为 0 表示不能提升为 master 。
slave-priority 100
#  如果少于 N 个 slave 连接,且延迟时间 <=M 秒,则 master 可配置停止接受写操作。
#  例如需要至少 3 个 slave 连接,且延迟 <=10 秒的配置:
# min-slaves-to-write 3# min-slaves-max-lag 10
#  设置 0 为禁用
#   默认 min-slaves-to-write 为 0 (禁用), min-slaves-max-lag 为 10
################################## 安全 ####################################  
设置客户端连接后进行任何其他指定前需要使用的密码。
#  警告:因为 redis 速度相当快,所以在一台比较好的服务器下,一个外部的用户可以在一秒钟进行 150K 次的密码尝试,
#  这意味着你需要指定非常非常强大的密码来防止暴力破解
# requirepass jfedu
#  命令重命名 .
#  在一个共享环境下可以重命名相对危险的命令。比如把 CONFIG 重名为一个不容易猜测的字符。
#  举例 :
# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
#  如果想删除一个命令,直接把它重命名为一个空字符 "" 即可,如下:
# rename-command CONFIG ""
###################################约束####################################
设置同一时间最大客户端连接数,默认无限制, 
#Redis 可以同时打开的客户端连接数为 Redis 进程可以打开的最大文件描述符数,
#如果设置  maxclients 0 ,表示不作限制。
#当客户端连接数到达限制时, Redis 会关闭新的连接并向客户端返回 max number of clients reached 错误信息
# maxclients 10000
#  指定 Redis 最大内存限制, Redis 在启动时会把数据加载到内存中,达到最大内存后, 
#  Redis 会按照清除策略尝试清除已到期的 Key
#  如果 Redis 依照策略清除后无法提供足够空间,或者策略设置为 ”noeviction” ,则使用更多空间的命令将会报错,
# 例如 SET, LPUSH 等。但仍然可以进行读取操作
#  注意: Redis 新的 vm 机制,会把 Key 存放内存, Value 会存放在 swap 区
#  该选项对 LRU 策略很有用。
# maxmemory 的设置比较适合于把 redis 当作于类似 memcached 的缓存来使用,而不适合当做一个真实的 DB 。
#  当把 Redis 当做一个真实的数据库使用的时候,内存使用将是一个很大的开销
# maxmemory <bytes>
#  当内存达到最大值的时候 Redis 会选择删除哪些数据?有五种方式可供选择
# volatile-lru ->  利用 LRU 算法移除设置过过期时间的 key (LRU: 最近使用  Least RecentlyUsed )
# allkeys-lru ->  利用 LRU 算法移除任何 key
# volatile-random ->  移除设置过过期时间的随机 keyallkeys->random -> remove a randomkey, any key
# volatile-ttl ->  移除即将过期的 key(minor TTL)
# noeviction ->  不移除任何可以,只是返回一个写错误
#  注意:对于上面的策略,如果没有合适的 key 可以移除,当写的时候 Redis 会返回一个错误
#  默认是 :  volatile-lru
# maxmemory-policy volatile-lru  
# LRU  和  minimal TTL 算法都不是精准的算法,但是相对精确的算法 ( 为了节省内存 ) ,
# 随意你可以选择样本大小进行检测。
# Redis 默认的灰选择 3 个样本进行检测,你可以通过 maxmemory-samples 进行设置
# maxmemory-samples 3
############################## AOF################################  
# 默认情况下, redis 会在后台异步的把数据库镜像备份到磁盘,但是该备份是非常耗时的,而且备份也不能很频繁,
# 如果发生诸如拉闸限电、拔插头等状况,那么将造成比较大范围的数据丢失。
#  所以 redis 提供了另外一种更加高效的数据库备份及灾难恢复方式。
#  开启 append only 模式之后, redis 会把所接收到的每一次写操作请求都追加到 appendonly.aof 文件中,
#  当 redis 重新启动时,会从该文件恢复出之前的状态。
#  但是这样会造成 appendonly.aof 文件过大,所以 redis 还支持了 BGREWRITEAOF 指令,对 appendonly.aof 进行重新整理。
#  你可以同时开启 asynchronous dumps 和  AOFappendonly  no# AOF 文件名称  ( 默认 : "appendonly.aof")
# appendfilename  appendonly.aof
# Redis 支持三种同步 AOF 文件的策略 :
# no:  不进行同步,系统去操作  . Faster.# always: always 表示每次有写操作都进行同步 . Slow, Safest.
# everysec:  表示对写操作进行累积,每秒同步一次 . 
Compromise.
#  默认是 "everysec" ,按照速度和安全折中这是最好的。
#  如果想让 Redis 能更高效的运行,你也可以设置为 "no"     ,让操作系统决定什么时候去执行
#  或者相反想让数据更安全你也可以设置为 "always"
#  如果不确定就用  "everysec".
# appendfsync always
appendfsync everysec
# appendfsync no
# AOF 策略设置为 always 或者 everysec 时,后台处理进程 ( 后台保存或者 AOF 日志重写 ) 会执行大量的 I/O 操作
#  在某些 Linux 配置中会阻止过长的 fsync() 请求。注意现在没有任何修复,即使 fsync 在另外一个线程进行处理
#  为了减缓这个问题,可以设置下面这个参数 no-appendfsync-on-rewriteno-appendfsync-on-rewrite no
#  当 AOF 文件增长到一定大小的时候 Redis 能够调用  BGREWRITEAOF  对日志文件进行重写
#  它是这样工作的: Redis 会记住上次进行些日志后文件的大小 ( 如果从开机以来还没进行过重写,
#  那日子大小在开机的时候确定 )
#  基础大小会同现在的大小进行比较。如果现在的大小比基础大小大制定的百分比,重写功能将启动
#  同时需要指定一个最小大小用于 AOF 重写,这个用于阻止即使文件很小但是增长幅度很大也去重写 AOF 文件的情况
#  设置  percentage 为 0 就关闭这个特性auto-aof-rewrite-percentage 100auto-aof-rewrite-min-size 64mb
######## # LUA SCRIPTING########## 
一个 Lua 脚本最长的执行时间为 5000 毫秒( 5 秒),如果为 0 或负数表示无限执行时间。
lua-time-limit 500
0################################LOW LOG################################# 
Redis Slow Log  记录超过特定执行时间的命令。执行时间不包括 I/O     
计算比如连接客户端,返回结果等,只是命令执行时间
#  可以通过两个参数设置 slow log :一个是告诉 Redis 执行超过多少时间被记录的参数 slowlog-log-slower-than( 微秒 ) 
#  另一个是 slow log 的长度。当一个新命令被记录的时候最早的命令将被从队列中移除
#  下面的时间以微秒为单位,因此 1000000 代表一秒。
#  注意指定一个负数将关闭慢日志,而设置为 0 将强制每个命令都会记录
slowlog-log-slower-than 10000
#  对日志长度没有限制,只是要注意它会消耗内存
#  可以通过  SLOWLOG RESET 回收被慢日志消耗的内存
#  推荐使用默认值 128 ,当慢日志超过 128 时,最先进入队列的记录会被踢出
slowlog-max-len 128

参考: http://noodle.blog.51cto.com/2925423/1731484

    http://wgkgood.blog.51cto.com/

     http://www.redis.cn/topics/replication.html