1.redis简介
REmote DIctionary Server(Redis)是一个几乎key-value键值对的持久化数据库存储系统。redis和大名鼎鼎的Memcached缓存服务很像,但是redis支持的数据存储类型更丰富,包括string(字符串)、list(链表)、set(集合)和zset(有序集合)等。
这些数据类型都支持push/pop、add/remove及取交集、并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached缓存服务一样,为了保证效率,数据都是缓存在内存中提供服务。和memcached不同的是,redis持久化服务还会周期的把更新的数据写入到磁盘以及把修改的操作记录追加到文件里记录下来,比memcached更有优势的是,redis还支持master-slave(主从)同步,这点很类似关系型数据库MySQL。
redis的出现,再一定程度上弥补了memcached这类key-value内存缓存的不足。在部分场合可以对关系型数据库起到很好的补充作用,redis提供了Python、Ruby、Erlang、PHP客户端,使用很方便。redis官方文档如下:
http://www.redis.io/documentation
2 Redis 的特点
1)性能很高:redis能支持超过100K+每秒的读写频率
2)丰富的数据类型:redis支持二进制的Strings、Lists、Hashes、Sets及Ordered Sets数据类型操作
3)原子:Redis的所有操作都是原子性的,同时redis还支持对几个操作合并后的原子执行
4)丰富的特性:Redis还支持publish/subscribe,通知,key过期等特性
5)redis支持异机主从复制
6)可以持久化存储数据,与memcached不同
3 Redis的数据类型
Redis最为常见的数据类型主要为有以下五种:
1)String
2)Hash
3)List
4)Set
5)Sorted set
4 redis的应用场景
传统的MySQL + Memcached 的网站架构遇到的问题:
MySQL数据库实际上适合进行海量数据存储的,加上通过Memcached将热点数据存放到内存cache里,达到加速数据访问的目的,绝大部分公司曾经使用过这样的架构,但随着业务数据的量的不断增加,和访问量的持续增长,很多问题就会暴露出来:
1)需要不断的对MySQL进行拆库拆表,Memcached也需要不断跟着扩容,扩容和维护工作占据大量开发运维时间
2)memcached与MySQL数据库一直性问题是个老大难。
3)memcached数据命中率低或者down机,会导致大量访问直接穿透到数据库,导致MySQL无法支撑访问
4)跨机房cache同步一致性问题
redis 的最佳应用场景:
1)Redis 最佳使用场景是全部数据in-memory
2)Redis更多场景是作为Memcached的替代品来使用
3)当需要除key/value之外的更多数据类型支持时,使用Redis更合适。
4)当存储的数据不能被剔除时,使用Redis更合适。
5) 需要负载均衡的场景(主从同步)
更多Redis作者谈Redis应用场景:http://blog.nosqlfan.com/html/2235.html
业务场景:
1、使用Redis bitmap进行活跃用户统计
http://blog.nosqlfan.com/html/3501.html
这里对Redis数据库做个小结
1)提高了DB的可扩展性,只需要将新加的数据放到新加的服务器上就开了
2)提高了DB的可用性,只影响到需要访问的shard服务器上的数据用户
3)提高了DB的可维护性,对系统的升级和配置可以按shard一个个来搞,对服务产生的影响较小
4)小的数据库的查询压力小,查询更快,性能更好
使用过程中的一些经验与教训,做个小结:
1)要进行Master-slave配置,出现服务器故障时可以直接切换。
2)在master侧禁用数据持久化,只需要在slave上配置数据持久化
3)物理内存+虚拟内存不足,这个时候dump一直死着,时间久了机器挂掉。这个情况就是灾难
4)当Redis物理内存使用超过内存总量的3/5时就会开始比较危险了,就开始做swap,内存碎片大
5)当达到最大内存时,会清空带有过期时间的key,即使key未到过期时间
6)redis与DB同步写的问题,先写DB,然后再写redis,因为写内存基本上没问题
redis部署环境搭建:
Master:192.168.1.7 Centos6.4
Slave:192.168.1.8 Centos6.4
开始安装redis服务
在redis的官网(http://www.redis.io)下载最新稳定版redis
操作命令:
mkdir -p /home/oldboy/tools
cd /home/oldboy/tools
wget -q http://download.redis.io/releases/redis-2.8.9.tar.gz
ls redis-2.8.9.tar.gz
tar xf redis-2.8.9.tar.gz
cd redis-2.8.9
meke MALLOC=jemalloc
make PREFIX=/application/redis-2.8.9 install
ln -s /application/redis-2.8.9/ /application/redis
LANG=EN
echo ‘vm.overcommit_memory = 1‘ >>/etc/sysctl.conf
sysctl -p
echo "export PATH=/application/redis/bin:$PATH" >>/etc/profile
source /etc/profile
mkdir -p /application/redis/conf
cp redis.conf /application/redis/conf/
redis-server /application/redis/conf/redis.conf &
[[email protected] redis-2.8.9]# tree /application/redis/bin/
/application/redis/bin/
|-- redis-benchmark
|-- redis-check-aof
|-- redis-check-dump
|-- redis-cli
`-- redis-server
0 directories, 5 files
[[email protected] redis-2.8.9]#
命令执行完成之后,会在/application/redis/bin下生成5个可执行文件,分别是:
redis-benchmark redis-check-aof redis-check-dump redis-cli redis-server
它们的作用如下:
redis-server,Redis服务器的daemon启动程序
redis-cli:Redis命令行操作工具,,当然,你也可以通过Telnet根据其纯文本协议来操作
redis-benchmark:Redis性能测试工具,测试Redis在你系统及你的配置下的读写性能
redis-check-aof:更新日志检查
redis-check-dump:用于本地数据库检查
配置并启动redis服务
a、配置环境变量
操作命令:
[[email protected] redis-2.8.9]# echo ‘PATH=/application/redis/bin:$PATH‘ >>/etc/profile
[[email protected] redis-2.8.9]# tail -1 /etc/profile
PATH=/application/redis/bin:$PATH
[[email protected] redis-2.8.9]# source /etc/profile
[[email protected] redis-2.8.9]#
b、查看帮助
[[email protected] redis-2.8.9]# redis-server --help
Usage: ./redis-server [/path/to/redis.conf] [options]
./redis-server - (read config from stdin)
./redis-server -v or --version
./redis-server -h or --help
./redis-server --test-memory <megabytes>
Examples:
./redis-server (run the server with default conf)
./redis-server /etc/redis/6379.conf
./redis-server --port 7777
./redis-server --port 7777 --slaveof 127.0.0.1 8888
./redis-server /etc/myredis.conf --loglevel verbose
Sentinel mode:
./redis-server /etc/sentinel.conf --sentinel
创建配置文件存放目录并将配置文件拷贝到其中:
[[email protected] redis-2.8.9]# mkdir -p /application/redis/conf
[[email protected] redis-2.8.9]# cp redis.conf /application/redis/conf/
启动redis服务:
[[email protected] redis-2.8.9]# redis-server /application/redis/conf/redis.conf &
[3017] 11 Jul 23:55:29.906 # Server started, Redis version 2.8.9
[3017] 11 Jul 23:55:29.906 # 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.
[3017] 11 Jul 23:55:29.906 * The server is now ready to accept connections on port 6379
[[email protected] redis-2.8.9]#
出现以上警告,将“vm.overcommit_memory = 1”添加到/etc/sysctl.conf中或者在命令行执行
这里直接添加到/etc/sysctl.conf
[[email protected] redis-2.8.9]# pkill redis-server
[[email protected] redis-2.8.9]# echo ‘vm.overcommit_memory = 1‘ >>/etc/sysctl.conf
[[email protected] redis-2.8.9]# tail -1 /etc/sysctl.conf
vm.overcommit_memory = 1
[[email protected] redis-2.8.9]#
运行sysctl -p使其生效:
[[email protected] redis-2.8.9]# sysctl -p
再次启动redis
[[email protected] redis-2.8.9]# redis-server /application/redis/conf/redis.conf &
[1] 3040
[[email protected] redis-2.8.9]# _._
_.-``__ ‘‘-._
_.-`` `. `_. ‘‘-._ Redis 2.8.9 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ‘‘-._
( ‘ , .-` | `, ) Running in stand alone mode
|`-._`-...-` __...-.``-._|‘` _.-‘| Port: 6379
| `-._ `._ / _.-‘ | PID: 3040
`-._ `-._ `-./ _.-‘ _.-‘
|`-._`-._ `-.__.-‘ _.-‘_.-‘|
| `-._`-._ _.-‘_.-‘ | http://redis.io
`-._ `-._`-.__.-‘_.-‘ _.-‘
|`-._`-._ `-.__.-‘ _.-‘_.-‘|
| `-._`-._ _.-‘_.-‘ |
`-._ `-._`-.__.-‘_.-‘ _.-‘
`-._ `-.__.-‘ _.-‘
`-._ _.-‘
`-.__.-‘
[3040] 12 Jul 00:01:52.043 # Server started, Redis version 2.8.9
[3040] 12 Jul 00:01:52.043 * DB loaded from disk: 0.000 seconds
[3040] 12 Jul 00:01:52.043 * The server is now ready to accept connections on port 6379
[[email protected] redis-2.8.9]#
从以上启动信息可以看出redis启动监听端口为6379,pid为3040
进一步验证端口和进程:
[[email protected] redis-2.8.9]# netstat -lnpt|grep redis-server
tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN 3040/redis-server *
tcp 0 0 :::6379 :::* LISTEN 3040/redis-server *
[[email protected] redis-2.8.9]#
redis服务关闭方法:
redis-cli shutdown
[[email protected] redis-2.8.9]# redis-cli shutdown
[3040] 12 Jul 00:06:46.122 # User requested shutdown...
[3040] 12 Jul 00:06:46.122 * Saving the final RDB snapshot before exiting.
[3040] 12 Jul 00:06:46.131 * DB saved on disk
[3040] 12 Jul 00:06:46.132 # Redis is now ready to exit, bye bye...
[1]+ Done redis-server /application/redis/conf/redis.conf
[[email protected] redis-2.8.9]# ps -ef|grep redis-server
root 3055 1174 0 00:06 pts/0 00:00:00 grep redis-server
[[email protected] redis-2.8.9]#
或者
[[email protected] redis-2.8.9]# netstat -lnpt|grep redis-server
[[email protected] redis-2.8.9]#
redis命令行帮助:
[[email protected] redis-2.8.9]# redis-cli --help
redis-cli 2.8.9
Usage: redis-cli [OPTIONS] [cmd [arg [arg ...]]]
-h <hostname> Server hostname (default: 127.0.0.1).
-p <port> Server port (default: 6379).
-s <socket> Server socket (overrides hostname and port).
-a <password> Password to use when connecting to the server.
-r <repeat> Execute specified command N times.
-i <interval> When -r is used, waits <interval> seconds per command.
It is possible to specify sub-second times like -i 0.1.
-n <db> Database number.
-x Read last argument from STDIN.
-d <delimiter> Multi-bulk delimiter in for raw formatting (default: \n).
-c Enable cluster mode (follow -ASK and -MOVED redirections).
--raw Use raw formatting for replies (default when STDOUT is
not a tty).
--csv Output in CSV format.
--latency Enter a special mode continuously sampling latency.
--latency-history Like --latency but tracking latency changes over time.
Default time interval is 15 sec. Change it using -i.
--slave Simulate a slave showing commands received from the master.
--rdb <filename> Transfer an RDB dump from remote server to local file.
--pipe Transfer raw Redis protocol from stdin to server.
--pipe-timeout <n> In --pipe mode, abort with error if after sending all data.
no reply is received within <n> seconds.
Default timeout: 30. Use 0 to wait forever.
--bigkeys Sample Redis keys looking for big keys.
--scan List all keys using the SCAN command.
--pattern <pat> Useful with --scan to specify a SCAN pattern.
--intrinsic-latency <sec> Run a test to measure intrinsic system latency.
The test will run for the specified amount of seconds.
--eval <file> Send an EVAL command using the Lua script at <file>.
--help Output this help and exit.
--version Output version and exit.
Examples:
cat /etc/passwd | redis-cli -x set mypasswd
redis-cli get mypasswd
redis-cli -r 100 lpush mylist x
redis-cli -r 100 -i 1 info | grep used_memory_human:
redis-cli --eval myscript.lua key1 key2 , arg1 arg2 arg3
redis-cli --scan --pattern ‘*:12345*‘
(Note: when using --eval the comma separates KEYS[] from ARGV[] items)
When no command is given, redis-cli starts in interactive mode.
Type "help" in interactive mode for information on available commands.
[[email protected] redis-2.8.9]#
redis-cli命令行操作:
[[email protected] redis-2.8.9]# redis-cli
127.0.0.1:6379>
127.0.0.1:6379> help
redis-cli 2.8.9
Type: "help @<group>" to get a list of commands in <group>
"help <command>" for help on <command>
"help <tab>" to get a list of possible help topics
"quit" to exit
127.0.0.1:6379>
127.0.0.1:6379> help set
SET key value [EX seconds] [PX milliseconds] [NX|XX]
summary: Set the string value of a key
since: 1.0.0
group: string
127.0.0.1:6379>
设置值,获取值:
提示:前面是键(key),后面是值(value)
127.0.0.1:6379> set no002 oldboy
OK
127.0.0.1:6379> get no002
"oldboy"
127.0.0.1:6379>
或者直接命令行(非交互模式):
[[email protected] redis-2.8.9]# redis-cli -h 192.168.1.12 -p 6379 set no001 zhangsan
OK
[[email protected] redis-2.8.9]# redis-cli -h 192.168.1.12 -p 6379 get no001
"zhangsan"
[[email protected] redis-2.8.9]#
删除数据(可以省略"-h 192.168.1.12 -p 6379"部分,默认):
[[email protected] redis-2.8.9]# redis-cli del no001
(integer) 1
[[email protected] redis-2.8.9]# redis-cli get no001
(nil)
通过Telnet命令连接redis
[[email protected] redis-2.8.9]# telnet 127.0.0.1 6379
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is ‘^]‘.
set 003 test
+OK
get 003
$4
test
set 005 linux
+OK
get 005
$5
linux
^]
quit
+OK
Connection closed by foreign host.
[[email protected] redis-2.8.9]#
字符串类型
这是最简单的Redis类型。如果你值用这种类型,Redis就是一个可以持久化的memcached服务器(注:memcached的数据仅保存在内存中,服务器重启后,数据将丢失)
我们来测试一下字符串类型:
[[email protected] redis-2.8.9]# redis-cli set mykey "my binary safe value"
OK
[[email protected] redis-2.8.9]# redis-cli get mykey
"my binary safe value"
[[email protected] redis-2.8.9]#
"my binary safe value"这正如你所见到的,通常用SET和GET来设置和获取字符串值。
值可以是任何类型的字符串(包括二进制数据),例如你可以在一个键下保存几个jpeg图片,值的长度不能超过1GB。
虽然字符串是Redis的基本类型,但你仍然能通过它完成一些有趣的操作。例如:
原子递增:
[[email protected] redis-2.8.9]# redis-cli set counter 100
OK
[[email protected] redis-2.8.9]# redis-cli incr counter
(integer) 101
[[email protected] redis-2.8.9]# redis-cli incr counter
(integer) 102
[[email protected] redis-2.8.9]# redis-cli incrby counter 10
(integer) 112
[[email protected] redis-2.8.9]#
INCR命令将字符串值解析成整形,将其加1,最后将结果保存为新的字符串值,类似的命令有INCRBY,DECR and DECRBY。实际上他们在内部就是一个命令,只是看上去有点不同。
INCR是原子操作意味什么呢?就是说即使多个客户端对同一个key发出INCR命令,也绝不会导致竞争的情况。例如如下情况永远不可能发生:【客户端1和客户端2同时读出“10”,他们俩都是对其加到11,然后将新值设置为11】,最终的值一定是12,read-increment-set操作完成时,其他客户端不会在同一时间执行任何命令。
对字符串,另一个的令人感兴趣的操作是GET SET命令,正如其名:它为key设置新值并且返回原值,这有什么用处呢?例如:你的系统每当所有新用户对访问时就用INCR命令操作一个Redis key。你希望每小时对这个信息收集一次,你就可以GET SET这个key并给其赋值0并读取原值。
列表类型:
要说清楚列表数据类型,最好先讲一点儿理论背景,在信息技术界List这个词常常被使用不当。例如"Python Lists"就是名不副实(Linked Lists),但他们实际上是数组(同样的数据类型在Ruby中叫数组)
一般意义上讲,列表就是有序元素的序列:10,20,1,2,3就是一个列表,但用数组实现的List和用Linked List实现list,在属性方面大不同。
Redis lists给予Linked Lists实现。这意味着即使在一个list中有百万个元素,在头部或者尾部添加一个元素操作,其时间复杂度也不是常数级别的,用LPUSH命令在十个元素的list头部添加新元素,和在千万元素list头部添加新元素的速度相同。
那么,坏消息是什么?在数组实现的list中利用索引访问元素的速度极快,而同样的操作在linked list实现的list上没有那么快。
Redis Lists are implemented with linked list because for a databases system it is crucial to be able to add elements to a very long list in a very fast way,Another strong advantage is,as you‘ll see in a moment,that Redis Lists can be taken at constant length in constant time。
Redis Lists 用linked list 实现的原因是:对于数据来说,之至关重要的特性是:能非常快的在很大的列表上添加元素。另一个重要元素是,正如你将要看到的:Redis lists能在常数时间取得常数长度。
Redis lists 入门
LPUSH命令可向list的左边(头部)添加一个新元素,而RPUSH命令可向list的右边(尾部)添加一个新元素。最后LRANGE命令可从list中取出一定范围的元素
[[email protected] redis-2.8.9]# redis-cli rpush messages "Hello how are you?"
(integer) 5
[[email protected] redis-2.8.9]# redis-cli rpush messages "Fine thanks,I‘m having fun with Redis"(integer) 6
[[email protected] redis-2.8.9]# redis-cli rpush messages "I should look into this NOSQL.thing ASAP"
(integer) 7
[[email protected] redis-2.8.9]# redis-cli lrange messages 0 2
1) "Hello how are you?"
2) "Hello how are you?"
3) "Fine thanks,I‘m having fun with Redis"
[[email protected] redis-2.8.9]# redis-cli lrange messages -2 0
(empty list or set)
[[email protected] redis-2.8.9]# redis-cli lrange messages -2 -1
1) "Fine thanks,I‘m having fun with Redis"
2) "I should look into this NOSQL.thing ASAP"
[[email protected] redis-2.8.9]# redis-cli lrange messages -2 0
(empty list or set)
[[email protected] redis-2.8.9]#
注意:LRANGE带有两个索引,一定范围的第一个和最后一个元素。这两个元素都可以为负来告知Redis从尾部开始计数,因此-1表示最后表示一个元素,-2表示list中的倒数第二个元素,以此类推。
Redis 集合是未排序的集合,其他元素是二进制安全的字符串。SADD命令可以向集合添加一个新元素。和sets相关的操作也有许多,iru检查某个元素是否存在,以及实现交集,并集,差集等等。一例胜于千言:
[[email protected] redis-2.8.9]# redis-cli sadd myset a
(integer) 1
[[email protected] redis-2.8.9]# redis-cli sadd myset b
(integer) 1
[[email protected] redis-2.8.9]# redis-cli sadd myset c
(integer) 1
[[email protected] redis-2.8.9]# redis-cli smembers myset
1) "b"
2) "c"
3) "a"
[[email protected] redis-2.8.9]#
我向集合中添加了三个元素,并让Redis返回所有元素。如你所见它们是无效的。现在让我们检查某个元素是否存在:
[[email protected] redis-2.8.9]# redis-cli sismember myset a
(integer) 1
[[email protected] redis-2.8.9]# redis-cli sismember myset d
(integer) 0
[[email protected] redis-2.8.9]#
"a"是这个集合的成员,而“d”不是。集合特别适合表现对象之间的关系。例如用Redis集合可以很容易实现标签功能。
下面是一个简单的方案:对每个想加标签的对象,用一个标签ID集合与之关联,并且对每个已有的标签,一组对象ID与之关联。
例如假设我们的新闻ID1000被加了三个标签tag 1,2,5和77,就可以设置下面两个集合:
[[email protected] redis-2.8.9]# redis-cli sadd names:1000:tags 1
(integer) 0
[[email protected] redis-2.8.9]# redis-cli sadd names:1000:tags 2
(integer) 1
[[email protected] redis-2.8.9]# redis-cli sadd names:1000:tags 5
(integer) 1
[[email protected] redis-2.8.9]#
[[email protected] redis-2.8.9]# redis-cli sadd names:1000:tags 77
(integer) 1
[[email protected] redis-2.8.9]# redis-cli sadd tag:1:objects 1000
(integer) 1
[[email protected] redis-2.8.9]# redis-cli sadd tag:2:objects 1000
(integer) 1
[[email protected] redis-2.8.9]# redis-cli sadd tag:5:objects 1000
(integer) 1
[[email protected] redis-2.8.9]#
要获取一个对象的所有标签,如此简单:
6 为PHP安装客户端扩展
获取源码包
wget https://github.com/nicolasff/phpredis/archive/master.zip
安装:
unzip phpredis-master.zip
cd phpredis-master
/application/php/bin/phpize
./configure --with-php-config=/application/php/bin/php-config
make
make install
修改php.ini设置,重启php
7 解读redis默认配置文件2.8.9
修改php配置文件php.ini如下两项:
[[email protected] extra]# cat /application/php/lib/php.ini
extension = redis.so
extension_dir = "/application/php5.3.27/lib/php/extensions/no-debug-non-zts-20090626/"
然后通过phpinfo函数检查php程序是否加载了redis模块,如下图:
如上图所示,php加载redis.so模块成功
redis主从复制:
在另外一台机器上安装redis(安装方法同上),然后修改配置文件:redis.conf
[[email protected] redis-2.8.9]# vim /application/redis/conf/redis.conf
--------------------省略部分-------------------
# so for example it is possible to configure the slave to save the DB with a
# different interval, or to listen to another port, and so on.
#
# slaveof <masterip> <masterport>
# If the master is password protected (using the "requirepass" configuration
# directive below) it is possible to tell the slave to authenticate before
将红色部分修改为:
slaveof 192.168.1.12 6379
其中IP地址192.168.1.12为主服务器IP,端口为主服务器端口
然后启动redis服务
[[email protected] redis-2.8.9]# redis-server /application/redis/conf/redis.conf &
[1] 5940
[[email protected] redis-2.8.9]# _._
_.-``__ ‘‘-._
_.-`` `. `_. ‘‘-._ Redis 2.8.9 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ‘‘-._
( ‘ , .-` | `, ) Running in stand alone mode
|`-._`-...-` __...-.``-._|‘` _.-‘| Port: 6379
| `-._ `._ / _.-‘ | PID: 5940
`-._ `-._ `-./ _.-‘ _.-‘
|`-._`-._ `-.__.-‘ _.-‘_.-‘|
| `-._`-._ _.-‘_.-‘ | http://redis.io
`-._ `-._`-.__.-‘_.-‘ _.-‘
|`-._`-._ `-.__.-‘ _.-‘_.-‘|
| `-._`-._ _.-‘_.-‘ |
`-._ `-._`-.__.-‘_.-‘ _.-‘
`-._ `-.__.-‘ _.-‘
`-._ _.-‘
`-.__.-‘
[5940] 13 Jul 00:54:54.591 # Server started, Redis version 2.8.9
[5940] 13 Jul 00:54:54.591 * DB loaded from disk: 0.000 seconds
[5940] 13 Jul 00:54:54.591 * The server is now ready to accept connections on port 6379
[5940] 13 Jul 00:54:54.591 * Connecting to MASTER 192.168.1.12:6379
[5940] 13 Jul 00:54:54.592 * MASTER <-> SLAVE sync started
[5940] 13 Jul 00:54:54.594 * Non blocking connect for SYNC fired the event.
[5940] 13 Jul 00:54:54.642 * Master replied to PING, replication can continue...
[5940] 13 Jul 00:54:54.642 * Partial resynchronization not possible (no cached master)
[5940] 13 Jul 00:54:54.653 * Full resync from master: ffb234a2db473390b99948ae8b9cdb9022aca489:1
[5940] 13 Jul 00:54:54.757 * MASTER <-> SLAVE sync: receiving 358 bytes from master
[5940] 13 Jul 00:54:54.757 * MASTER <-> SLAVE sync: Flushing old data
[5940] 13 Jul 00:54:54.757 * MASTER <-> SLAVE sync: Loading DB in memory
[5940] 13 Jul 00:54:54.757 * MASTER <-> SLAVE sync: Finished with success
[[email protected] redis-2.8.9]#
再在主服务器这边查看:
[[email protected] conf]# [3248] 13 Jul 00:54:54.286 * Slave asks for synchronization
[3248] 13 Jul 00:54:54.297 * Full resync requested by slave.
[3248] 13 Jul 00:54:54.297 * Starting BGSAVE for SYNC
[3248] 13 Jul 00:54:54.299 * Background saving started by pid 8601
[8601] 13 Jul 00:54:54.332 * DB saved on disk
[8601] 13 Jul 00:54:54.341 * RDB: 0 MB of memory used by copy-on-write
[3248] 13 Jul 00:54:54.401 * Background saving terminated with success
[3248] 13 Jul 00:54:54.401 * Synchronization with slave succeeded
经过这边的发现主两边已经同步,下面进行测试:
在主服务器端进行写入数据:
[[email protected] conf]# redis-cli
127.0.0.1:6379> set 001 redistest
OK
127.0.0.1:6379> get 001
"redistest"
127.0.0.1:6379>
然后在从服务器端查看:
[[email protected] redis-2.8.9]# redis-cli
127.0.0.1:6379> get 001
"redistest"
127.0.0.1:6379>
发现在从服务器端可以获取到值 redistest
再次主服务器写入数据:
从库继续查看:
现在从库做一个监控:redis-cli -h localhost -p 6379 monitor
然后在主库进行写入数据:
再观察从库:
发现数据已经从主库同步到从库
这里从主库退出,再从主库连接到从库上,进行取数据:
发现可以取到刚才主库写入的数据
统计信息:
redis-cli -h localhost -p 6379 info
[[email protected] conf]# redis-cli -h localhost -p 6379 info
# Server
redis_version:2.8.9
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:f4fef593e6e0c11c
redis_mode:standalone
os:Linux 2.6.32-358.el6.x86_64 x86_64
arch_bits:64
multiplexing_api:epoll
gcc_version:4.4.7
process_id:3248
run_id:ffb234a2db473390b99948ae8b9cdb9022aca489
tcp_port:6379
uptime_in_seconds:82589
uptime_in_days:0
hz:10
lru_clock:10657853
config_file:/application/redis/conf/redis.conf
# Clients
connected_clients:1
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0
# Memory
used_memory:1881496
used_memory_human:1.79M
used_memory_rss:2367488
used_memory_peak:1916864
used_memory_peak_human:1.83M
used_memory_lua:33792
mem_fragmentation_ratio:1.26
mem_allocator:jemalloc-3.2.0
# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1436720995
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:0
rdb_current_bgsave_time_sec:-1
aof_enabled:0
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
# Stats
total_connections_received:5
total_commands_processed:1120
instantaneous_ops_per_sec:1
rejected_connections:0
sync_full:1
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
evicted_keys:0
keyspace_hits:3
keyspace_misses:0
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:318
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.1.10,port=6379,state=online,offset=1845,lag=0
master_repl_offset:1845
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:1844
# CPU
used_cpu_sys:178.05
used_cpu_user:97.68
used_cpu_sys_children:0.02
used_cpu_user_children:0.02
# Keyspace
db0:keys=18,expires=0,avg_ttl=0
[[email protected] conf]#
如果想统计某一段,就在后面直接跟标签名即可:
[[email protected] conf]# redis-cli -h localhost -p 6379 info Replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.1.10,port=6379,state=online,offset=2181,lag=1
master_repl_offset:2195
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:2194
[[email protected] conf]# redis-cli -h localhost -p 6379 info CPU
# CPU
used_cpu_sys:178.42
used_cpu_user:97.91
used_cpu_sys_children:0.02
used_cpu_user_children:0.02
[[email protected] conf]#
[[email protected] conf]# redis-cli -h localhost -p 6379 info Memory
# Memory
used_memory:1880776
used_memory_human:1.79M
used_memory_rss:2371584
used_memory_peak:1916864
used_memory_peak_human:1.83M
used_memory_lua:33792
mem_fragmentation_ratio:1.26
mem_allocator:jemalloc-3.2.0
[[email protected] conf]#
[[email protected] conf]# redis-cli -h localhost -p 6379 info stats
# Stats
total_connections_received:11
total_commands_processed:1530
instantaneous_ops_per_sec:1
rejected_connections:0
sync_full:1
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
evicted_keys:0
keyspace_hits:3
keyspace_misses:0
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:318
[[email protected] conf]#
提示:也可以在交互模式下执行以上命令
master和slave安装配置过程如下:
#1.wget
#tar zxvf redis-2.8.19.tar.gz
#cd redis-2.8.19/src/
#vi Makefile
PREFIX?=/opt/etc/redis
#make && make install
#redis_6309.conf
daemonize yes
pidfile /var/run/redis_6309.pid
port 6309
tcp-backlog 10240
timeout 600
tcp-keepalive 60
loglevel notice
logfile stdout
logfile /data/log/redis/redis_6309.log
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data/redis/redis_6309/
slave-serve-stale-data yes
slave-read-only yes
repl-disable-tcp-nodelay no
slave-priority 100
maxmemory 4gb
maxmemory-policy allkeys-lru
appendonly no
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
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
hz 10
#/opt/etc/redis/bin/redis-server /opt/etc/redis/conf/redis_6309.conf
#SLAVE 配置
daemonize yes
pidfile /var/run/redis_6309.pid
port 6309
tcp-backlog 10240
timeout 600
tcp-keepalive 60
loglevel notice
logfile stdout
logfile /data/log/redis/redis_6309.log
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data/redis/redis_6309/
slave-serve-stale-data yes
slave-read-only yes
repl-disable-tcp-nodelay no
slaveof 10.0.20.14 6309
slave-priority 100
maxmemory 4gb
maxmemory-policy allkeys-lru
appendonly no
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
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
hz 10
二,redis master 非持久化,备持久化
2.1 master
#redis 6309
daemonize yes
pidfile /var/run/redis.pid
port 6309
tcp-backlog 10240
timeout 0
tcp-keepalive 0
loglevel notice
logfile stdout
logfile /var/log/redis/redis_6309.log
databases 16
#save 900 1
#save 300 10
#save 60 10000
save ""
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/lib/redis_6309/
slave-serve-stale-data yes
slave-read-only yes
repl-disable-tcp-nodelay no
slave-priority 100
maxmemory 4gb
maxmemory-policy allkeys-lru
appendonly yes
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
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
hz 10
#redis 6310
more redis_6310.conf
daemonize yes
pidfile /var/run/redis_6310.pid
port 6310
tcp-backlog 10240
timeout 0
tcp-keepalive 0
loglevel notice
logfile stdout
logfile /var/log/redis/redis_6310.log
databases 16
#save 900 1
#save 300 10
#save 60 10000
save ""
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/lib/redis_6310/
slave-serve-stale-data yes
slave-read-only yes
repl-disable-tcp-nodelay no
slave-priority 100
maxmemory 4gb
maxmemory-policy allkeys-lru
appendonly yes
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
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
hz 10
2.2 salve
#redis 6309
daemonize yes
pidfile /var/run/redis.pid
port 6309
tcp-backlog 10240
timeout 0
tcp-keepalive 0
loglevel notice
logfile stdout
logfile /data/redis/logs/redis_6309.log
databases 16
save 900 1
save 300 10
save 60 10000
save ""
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data/redis/6309/redis_6309/
slave-serve-stale-data yes
slave-read-only yes
slaveof 10.0.20.179 6309
repl-disable-tcp-nodelay no
slave-priority 100
maxmemory 4gb
maxmemory-policy allkeys-lru
appendonly no
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
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
hz 10
#redis_6310
more redis_6310.conf
daemonize yes
pidfile /var/run/redis_6310.pid
port 6310
tcp-backlog 10240
timeout 0
tcp-keepalive 0
loglevel notice
logfile stdout
logfile /data/redis/logs/redis_6310.log
databases 16
save 900 1
save 300 10
save 60 10000
save ""
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data/redis/6310/redis_6310/
slave-serve-stale-data yes
slave-read-only yes
slaveof 10.0.20.179 6310
repl-disable-tcp-nodelay no
slave-priority 100
maxmemory 4gb
maxmemory-policy allkeys-lru
appendonly no
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
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
hz 10