redis
redis简介
redis的官网地址 https://redis.io/ 目前,Vmware在资助着redis项目的开发和维护
redis(Remote Dictionary Server)是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,
包括string(字符串)、list(列表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。
这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。
在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。
与memcached区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。 Redis 是一个高性能的key-value数据库。 redis的出现,很大程度弥补memcached这类key/value存储的不足,在部分场合可以对关系数据库起到很好的补充作用。
它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。 Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。
这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,
可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。
redis的优点
数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。
可以持久化存储数据
性能极高 – Redis能支持超过 100K+ 每秒的读写频率。
丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。
丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
支持异机主从同步
Memcached Redis
类型 Key-value数据库 Key-value数据库
过期策略 支持 支持
数据类型 单一数据 五种数据(字符串类型(String)、散列类型(Hash)、列表类型(List)、集合类型(SET)、有序集合类型(SortSet))
持久化 不支持 支持
主从复制 不支持 支持
虚拟内存 不支持 支持(不要用)
传统MySQL+ Memcached架构遇到的问题
实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,
但随着业务数据量的不断增加,和访问量的持续增长,我们遇到了很多问题:
MySQL需要不断进行拆库拆表,Memcached也需不断跟着扩容,扩容和维护工作占据大量开发时间。
Memcached与MySQL数据库数据一致性问题。
Memcached数据命中率低或down机,大量访问直接穿透到DB,MySQL无法支撑。
跨机房cache同步问题。
Redis的最佳应用场景
Redis使用最佳方式是全部数据in-memory。 Redis更多场景是作为Memcached的替代者来使用,并且支持持久化。 当需要除key/value之外的更多数据类型支持时,使用Redis更合适。 当存储的数据不能被剔除时,使用Redis更合适。 需要负载均衡的场景(redis主从同步)
redis安装
wget http://download.redis.io/releases/redis-3.2.3.tar.gz tar zxvf redis-3.2.3.tar.gz cd redis-3.2.3 make MALLOC=jemalloc make PREFIX=/usr/local/redis-3.2.3 install ln -s /usr/local/redis-3.2.3/ /usr/local/redis #tree /usr/local/redis
/usr/local/redis
`-- bin
|-- redis-benchmark 性能测试工具,测试redis在你的系统以及你的配置下的读写性能
|-- redis-check-aof 更新日志检查
|-- redis-check-rdb 用于本地数据库检查
|-- redis-cli redis命令行操作工具,也可以tenet
|-- redis-sentinel -> redis-server
`-- redis-server redis服务器的daemon启动程序
#源码包的util目录有启动脚本,可以拷贝至/etc/init.d目录,修改相关路径,包括redis.conf路径
环境变量设置
#echo "PATH=/usr/local/redis/bin/:$PATH" >>/etc/profile
#source /etc/profile
创建配置文件
#mkdir /usr/local/redis/conf
#cp /home/tools/redis-3.2.3/redis.conf /usr/local/redis/conf
#vi /usr/local/redis/conf/redis.conf
主要参数
daemonize no 设为daemon模式,可改为yes
bind 192.168.0.86 监听ip,默认只监听127.0.0.1
loglevel warning 设置log级别
logfile "/var/log/redis" 设置log日志
dir ./ 设置持久化存目录
# 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
# redis-server /usr/local/redis/conf/redis.conf
29598:M 30 Jan 08:21:28.988 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
29598:M 30 Jan 08:21:28.988 # Server started, Redis version 3.2.3
29598:M 30 Jan 08:21:28.988 # 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.
29598:M 30 Jan 08:21:28.988 # 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
29598:M 30 Jan 08:21:28.988 * The server is now ready to accept connections on port 6379 默认前台
作相应调整后再次启动
sysctl vm.overcommit_memory=1
echo 1024 > /proc/sys/net/core/somaxconn
echo never > /sys/kernel/mm/transparent_hugepage/enabled
redis-server /usr/local/redis/conf/redis.conf & 没有warning后放入后台运行
# redis-cli -h 192.168.0.86 -p 6379 shutdown redis的关闭
29618:M 30 Jan 09:01:01.088 # User requested shutdown...
29618:M 30 Jan 09:01:01.088 * Saving the final RDB snapshot before exiting.
29618:M 30 Jan 09:01:01.135 * DB saved on disk
29618:M 30 Jan 09:01:01.135 * Removing the pid file.
29618:M 30 Jan 09:01:01.135 # Redis is now ready to exit, bye bye...
info 全局状态统计# Server# Clients# Memory# Persistence# Stats# Replication# CPU# Cluster# Keyspace flushall 删除所有数据
config set 动态调整redis配置
Redis文档 http://doc.redisfans.com/
KEY的基本操作
KEY的基本操作
SET 设置key
GET 获取key的值
EXISTS 判断key是否存在
KEYS 显示所有的key
DEL 删除指定key
TYPE 获取key的类型
# redis-cli -h 192.168.0.86 -p 6379 192.168.0.86:6379> set where1 shanghai OK 192.168.0.86:6379> set where2 shenzhen OK 192.168.0.86:6379> keys * #取得所有key 1) "where1" 2) "where2" 192.168.0.86:6379> keys where? #匹配key 1) "where1" 2) "where2" 192.168.0.86:6379> get where1 #取key的值 "shanghai"
192.168.0.86:6379> type where1 #key的类型
string
192.168.0.86:6379> exists where1 #判断key是否存在,返回值1为存在
(integer) 1
192.168.0.86:6379> del where1 where2 #删除key,返回值为删除的数量
(integer) 2
字符串类型基本操作
字符串操作
SET 赋值,用法: SET key value
GET 取值,用法: GET key
INCR 递增数字 用法: INCR key
INCRBY 增加指定的数字用法:INCRBY key increment
DECR 递减数字 用法:DECR key
DECRBY 减少指定的数字 用法:DECRBY key decrement
INCRBYFLOAT 增加指定浮点数,仅仅对数字类型的键有用,用法:INCRBYFLOAT key increment
APPEND 向尾部追加值 用法:APPEND key value
STRLEN 获取字符串长度,用法:STRLEN key
MSET 同时设置多个key的值,用法:MSET key1 value1 [key2 value2 ...]
MGET 同时获取多个key的值,用法:MGET key1 [key2 ...]
192.168.0.86:6379> set where1 shanghai
OK
192.168.0.86:6379> get where1
"shanghai"
192.168.0.86:6379> append where1 hello
(integer) 13
192.168.0.86:6379> get where1
"shanghaihello"
192.168.0.86:6379> incr num
(integer) 1
192.168.0.86:6379> get num
"1"
192.168.0.86:6379> incr num
(integer) 2
192.168.0.86:6379> incr num
(integer) 3
192.168.0.86:6379> get num
"3"
192.168.0.86:6379> incrby num 10
(integer) 13
192.168.0.86:6379> get num
"13"
192.168.0.86:6379> decr num
(integer) 12
192.168.0.86:6379> decr num
(integer) 11
192.168.0.86:6379> decrby num 5
(integer) 6
192.168.0.86:6379> get num
"6"
192.168.0.86:6379> incrbyfloat num 0.1
"6.1"
192.168.0.86:6379> incrbyfloat num 0.2
"6.3"
192.168.0.86:6379> mset post1 shanghai post2 shenzhen
OK
192.168.0.86:6379> mget post1 post2
1) "shanghai"
2) "shenzhen"
192.168.0.86:6379> strlen post1
(integer) 8
哈希类型基本操作
hash类型基本操作
HSET key field value
hget key field
hmset key field value [field value ...]
hmget key field [field ...]
hgetall key
hdel key field [field ...]
hexists key field
exists key [key ...]
192.168.0.86:6379> hset phone name huawei-p7
(integer) 1
192.168.0.86:6379> hset phone colour red
(integer) 1
192.168.0.86:6379> hset phone price 2988
(integer) 1
192.168.0.86:6379> hgetall phone
1) "name"
2) "huawei-p7"
3) "colour"
4) "red"
5) "price"
6) "2988"
192.168.0.86:6379> hget phone name
"huawei-p7"
192.168.0.86:6379> hget phone colour
"red"
192.168.0.86:6379> hmset computer name dell colour black price 6888
OK
192.168.0.86:6379> hgetall computer
1) "name"
2) "dell"
3) "colour"
4) "black"
5) "price"
6) "6888"
192.168.0.86:6379> hdel computer price
(integer) 1
列表(队列)类型基本操作
list类型基本操作
lpush key value [value ...]
rpush key value [value ...]
lpop key
rpop key
lrange key start stop
lrem key count value
lindex key index
ltrim key start stop 截取只保留
192.168.0.86:6379> lpush list1 b
(integer) 1
192.168.0.86:6379> lpush list1 a
(integer) 2
192.168.0.86:6379> rpush list1 c
(integer) 3
192.168.0.86:6379> lrange list1 0 2
1) "a"
2) "b"
3) "c"
192.168.0.86:6379> lrange list1 0 -2
1) "a"
2) "b"
192.168.0.86:6379> lindex list1 1
"b"
192.168.0.86:6379> lpop list1
"a"
192.168.0.86:6379> rpop list1
"c"
192.168.0.86:6379> llen list1
(integer) 1
集合类型基本操作
集合基本操作命令(无序)
sadd key member [member ...]
srem key member [member ...]
smembers key
sismember key member
sdiff key [key ...] 差集
sinter key [key ...] 交集
sunion key [key ...] 并集
192.168.0.83:6379> sadd myset1 a b c
(integer) 3
192.168.0.83:6379> sadd myset2 b c d
(integer) 3
192.168.0.83:6379> SMEMBERS myset1
1) "c"
2) "b"
3) "a"
192.168.0.83:6379> smembers myset1
1) "c"
2) "b"
3) "a"
192.168.0.83:6379> sismember myset1 a
(integer) 1
192.168.0.83:6379> sdiff myset1 myset2
1) "a"
192.168.0.83:6379> sinter myset1 myset2
1) "c"
2) "b"
192.168.0.83:6379> sunion myset1 myset2
1) "a"
2) "b"
3) "c"
4) "d"
集合基本操作命令(有序)
ZADD key [NX|XX] [CH] [INCR] score member [score member ...]
ZSCORE key member
ZRANGE key start stop [WITHSCORES]
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
192.168.0.83:6379> zadd mysort1 10 a
(integer) 1
192.168.0.83:6379> zadd mysort1 11 b
(integer) 1
192.168.0.83:6379> zadd mysort1 12 c
(integer) 1
192.168.0.83:6379> zadd mysort1 13 d 14 e
(integer) 2
192.168.0.83:6379> zscore mysort1 a
"10"
192.168.0.83:6379> zrange mysort1 0 3
1) "a"
2) "b"
3) "c"
4) "d"
192.168.0.83:6379> zadd mysort1 9 f
(integer) 1
192.168.0.83:6379> zrange mysort1 0 3
1) "f"
2) "a"
3) "b"
4) "c"
redis持久化
redis持久化 RDB方式(默认) 该机制是指在指定的时间间隔内将内存中的数据集快照写入磁盘。 AOF方式 该机制将以日志的形式记录服务器所处理的每一个写操作,在Redis服务器启动之初会读取该文 件来重新构建数据库,以保证启动后数据库中的数据是完整的。重写机制,自动去除无效句 AOF和RDB同时应用 RDB方式( redis.conf) ################################ SNAPSHOTTING ################################ # In the example below the behaviour will be to save: # after 900 sec (15 min) if at least 1 key changed # after 300 sec (5 min) if at least 10 keys changed # after 60 sec if at least 10000 keys changed save 900 1 900s内如果有1个key更新(执行save即刻执行bgsave后台执行) save 300 10 save 60 10000 #上述3行注释就代表禁用 #kill -9容易丢数据 dbfilename dump.rdb 指定名称,redis启动时会载入 dir ./ 修改指定保存目录(aof备份也在这) Dump快照的机制: 1). Redis先fork子进程。数据量大时耗时,消耗资源,性能影响 2). 子进程将快照数据写入到临时RDB文件中。 3). 当子进程完成数据写入操作后,再用临时文件替换老的文件。 3) save阻塞进行,bgsave后台进行save AOF方式( redis.conf),类似binlog ############################## APPEND ONLY MODE ############################### appendonly no #改成yes开启 appendfilename "appendonly.aof" #指定名称 # appendfsync always #每次有数据修改发生时都会写入AOF文件。 appendfsync everysec #每秒钟同步一次,该策略为AOF的缺省策略。 # appendfsync no #从不同步。高效但是数据不会被持久化。
redis主从同步
redis主从同步(完成后可以实现在前端架设lvs实现负载均衡rr轮询) #从服务器只读# Since Redis 2.6 by default slaves are read-only. 全量同步过程 slave发送SYNC master执行bgsave生成RDB快照文件,同时将这之后新的写命令记入缓冲区 master向slave发送快照文件,并继续记录写命令 slave接收并保存快照 slave将快照文件载入内存 slave开始接收master中缓冲区的命令完成同步 redis从服务器配置 #vi /usr/local/redis/conf/redis.conf # slaveof <masterip> <masterport> slaveof 192.168.0.86 6379 启动从redis #redis-server /usr/local/redis/conf/redis.conf & #或者直接redis-cli中直接SLAVEOF host port 4780:S 31 Jan 16:06:39.832 # Server started, Redis version 3.2.3 4780:S 31 Jan 16:06:39.832 * DB loaded from disk: 0.000 seconds 4780:S 31 Jan 16:06:39.832 * The server is now ready to accept connections on port 6379 4780:S 31 Jan 16:06:39.833 * Connecting to MASTER 192.168.0.86:6379 4780:S 31 Jan 16:06:39.834 * MASTER <-> SLAVE sync started 4780:S 31 Jan 16:06:39.835 * Non blocking connect for SYNC fired the event. 4780:S 31 Jan 16:06:39.854 * Master replied to PING, replication can continue... 4780:S 31 Jan 16:06:39.854 * Partial resynchronization not possible (no cached master) 4780:S 31 Jan 16:06:39.879 * Full resync from master: 7a9946b4bfa81d6731b51bcde8344e6cc60f570f:1 4780:S 31 Jan 16:06:39.980 * MASTER <-> SLAVE sync: receiving 86 bytes from master 4780:S 31 Jan 16:06:39.984 * MASTER <-> SLAVE sync: Flushing old data 4780:S 31 Jan 16:06:39.984 * MASTER <-> SLAVE sync: Loading DB in memory 4780:S 31 Jan 16:06:39.985 * MASTER <-> SLAVE sync: Finished with success 从库设置监控 [root@node87 redis-3.2.3]# redis-cli -h 192.168.0.87 -p 6379 monitor OK 1485850642.936064 [0 192.168.0.86:6379] "PING" 1485850653.039262 [0 192.168.0.86:6379] "PING" 1485850663.143399 [0 192.168.0.86:6379] "PING" 1485850673.248709 [0 192.168.0.86:6379] "PING" 1485850675.674769 [0 192.168.0.86:6379] "SELECT" "0" 1485850675.674780 [0 192.168.0.86:6379] "set" "t1" "gtms1" 1485850682.915669 [0 192.168.0.86:6379] "set" "t2" "gtms2" 1485850683.352850 [0 192.168.0.86:6379] "PING" 1485850693.458079 [0 192.168.0.86:6379] "PING" [root@node86 ~]# redis-cli -h 192.168.0.86 192.168.0.86:6379> set t1 gtms1 OK 192.168.0.86:6379> set t2 gtms2 OK
192.168.0.87:6379> info Replication
# Replication
role:slave
master_host:192.168.0.86
master_port:6379
master_link_status:up
master_last_io_seconds_ago:4
master_sync_in_progress:0
slave_repl_offset:1446
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
redis cluster
=============================================================================== redis集群 =============================================================================== 四种大方案 客户端分片 proxy代理分片:Twemproxy redis cluster 无中心(可能用的不多) codis豌豆荚(推荐) 集群简介 Redis 集群是一个可以在多个 Redis 节点之间进行数据共享的设施(installation)。 Redis 集群不支持那些需要同时处理多个键的 Redis 命令, 因为执行这些命令需要在多个 Redis 节点之间移动数据, 并且在高负载的情况下, 这些命令将降低 Redis 集群的性能, 并导致不可预测的行为。 Redis 集群通过分区(partition)来提供一定程度的可用性(availability): 即使集群中有一部分节点失效或者无法进行通讯, 集群也可以继续处理命令请求。 Redis 集群提供了以下两个好处: 将数据自动切分(split)到多个节点的能力。 当集群中的一部分节点失效或者无法进行通讯时, 仍然可以继续处理命令请求的能力。 Redis 集群数据共享 Redis 集群使用数据分片(sharding)而非一致性哈希(consistency hashing)来实现: 一个 Redis 集群包含 16384 个哈希槽(hash slot), 数据库中的每个键都属于这 16384 个哈希槽的其中一个, 集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽, 其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和 。 集群中的每个节点负责处理一部分哈希槽。 举个例子, 一个集群可以有三个哈希槽, 其中: 节点 A 负责处理 0 号至 5500 号哈希槽。 节点 B 负责处理 5501 号至 11000 号哈希槽。 节点 C 负责处理 11001 号至 16384 号哈希槽。 这种将哈希槽分布到不同节点的做法使得用户可以很容易地向集群中添加或者删除节点。 比如说: 如果用户将新节点 D 添加到集群中, 那么集群只需要将节点 A 、B 、 C 中的某些槽移动到节点 D 就可以了。 与此类似, 如果用户要从集群中移除节点 A , 那么集群只需要将节点 A 中的所有哈希槽移动到节点 B 和节点 C , 然后再移除空白(不包含任何哈希槽)的节点 A 就可以了。 因为将一个哈希槽从一个节点移动到另一个节点不会造成节点阻塞, 所以无论是添加新节点还是移除已存在节点, 又或者改变某个节点包含的哈希槽数量, 都不会造成集群下线。 Redis 集群中的主从复制 为了使得集群在一部分节点下线或者无法与集群的大多数(majority)节点进行通讯的情况下, 仍然可以正常运作, Redis 集群对节点使用了主从复制功能: 集群中的每个节点都有 1 个至 N 个复制品(replica), 其中一个复制品为主节点(master), 而其余的 N-1 个复制品为从节点(slave)。 在之前列举的节点 A 、B 、C 的例子中, 如果节点 B 下线了, 那么集群将无法正常运行, 因为集群找不到节点来处理 5501 号至 11000 号的哈希槽。 另一方面, 假如在创建集群的时候(或者至少在节点 B 下线之前), 我们为主节点 B 添加了从节点 B1 , 那么当主节点 B 下线的时候, 集群就会将 B1 设置为新的主节点, 并让它代替下线的主节点 B , 继续处理 5501 号至 11000 号的哈希槽, 这样集群就不会因为主节点 B 的下线而无法正常运作了。 不过如果节点 B 和 B1 都下线的话, Redis 集群还是会停止运作。 Redis 集群的一致性保证(guarantee) Redis 集群不保证数据的强一致性(strong consistency): 在特定条件下, Redis 集群可能会丢失已经被执行过的写命令。 使用异步复制(asynchronous replication)是 Redis 集群可能会丢失写命令的其中一个原因。 考虑以下这个写命令的例子: 客户端向主节点 B 发送一条写命令。 主节点 B 执行写命令,并向客户端返回命令回复。 主节点 B 将刚刚执行的写命令复制给它的从节点 B1 、 B2 和 B3 。 如你所见, 主节点对命令的复制工作发生在返回命令回复之后, 因为如果每次处理命令请求都需要等待复制操作完成的话, 那么主节点处理命令请求的速度将极大地降低 —— 我们必须在性能和一致性之间做出权衡。 如果真的有必要的话, Redis 集群可能会在将来提供同步地(synchronou)执行写命令的方法。 Redis 集群另外一种可能会丢失命令的情况是, 集群出现网络分裂(network partition), 并且一个客户端与至少包括一个主节点在内的少数(minority)实例被孤立。 举个例子, 假设集群包含 A 、 B 、 C 、 A1 、 B1 、 C1 六个节点, 其中 A 、B 、C 为主节点, 而 A1 、B1 、C1 分别为三个主节点的从节点, 另外还有一个客户端 Z1 。 假设集群中发生网络分裂, 那么集群可能会分裂为两方, 大多数(majority)的一方包含节点 A 、C 、A1 、B1 和 C1 , 而少数(minority)的一方则包含节点 B 和客户端 Z1 。 在网络分裂期间, 主节点 B 仍然会接受 Z1 发送的写命令: 如果网络分裂出现的时间很短, 那么集群会继续正常运行; 但是, 如果网络分裂出现的时间足够长, 使得大多数一方将从节点 B1 设置为新的主节点, 并使用 B1 来代替原来的主节点 B , 那么 Z1 发送给主节点 B 的写命令将丢失。 注意, 在网络分裂出现期间, 客户端 Z1 可以向主节点 B 发送写命令的最大时间是有限制的, 这一时间限制称为节点超时时间(node timeout), 是 Redis 集群的一个重要的配置选项: 对于大多数一方来说, 如果一个主节点未能在节点超时时间所设定的时限内重新联系上集群, 那么集群会将这个主节点视为下线, 并使用从节点来代替这个主节点继续工作。 对于少数一方, 如果一个主节点未能在节点超时时间所设定的时限内重新联系上集群, 那么它将停止处理写命令, 并向客户端报告错误。 创建集群 # cd /usr/local/redis/conf/ # for i in `seq 7001 7008`;do cp redis.conf redis$i.conf ;done 相关更改参数如下 daemonize yes port 7001 pidfile /var/run/redis7001.pid logfile "/var/log/redis7001.log" dbfilename dump.rdb dir /redisfile/7001/ 注意后面的斜杠 #for i in `seq 7001 7008`;do mkdir -p /redisfile/$i;done appendonly yes cluster-enabled yes cluster-config-file node.conf 自动维护 cluster-node-timeout 5000 #sed -i s#7001#7002# redis7002.conf ........ 启#for i in `ls /usr/local/redis/conf/`;do /usr/local/redis/bin/redis-server /usr/local/redis/conf/$i;done 停#for i in `seq 7001 7008` ;do redis-cli -h 192.168.0.86 -p $i shutdown; done 默认有个集群管理工具,是ruby写的 # yum install ruby rubygems # gem install redis # cp /home/tools/redis-3.2.3/src/redis-trib.rb /usr/local/redis/bin/redis-trib [root@node90 bin]# redis-trib help Usage: redis-trib <command> <options> <arguments ...> call host:port command arg arg .. arg check host:port import host:port --from <arg> --replace --copy add-node new_host:new_port existing_host:existing_port --slave --master-id <arg> rebalance host:port --pipeline <arg> --use-empty-masters --threshold <arg> --simulate --auto-weights --weight <arg> --timeout <arg> help (show this help) reshard host:port --from <arg> --yes --slots <arg> --pipeline <arg> --to <arg> --timeout <arg> fix host:port --timeout <arg> set-timeout host:port milliseconds del-node host:port node_id create host1:port1 ... hostN:portN --replicas <arg> info host:port For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster. # redis-trib create --replicas 1 192.168.0.86:7001 192.168.0.86:7002 192.168.0.86:7003 192.168.0.86:7004 192.168.0.86:7005 192.168.0.86:7006
#前三是主,--replicas 1不加的话全是主 >>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.0.86:7001
192.168.0.86:7002
192.168.0.86:7003
Adding replica 192.168.0.86:7004 to 192.168.0.86:7001
Adding replica 192.168.0.86:7005 to 192.168.0.86:7002
Adding replica 192.168.0.86:7006 to 192.168.0.86:7003
M: f49a220719ecfdb1e36cd14b3eeb7f4ac011c753 192.168.0.86:7001
slots:0-5460 (5461 slots) master
M: 8bf30c7084cae9c9baca14b00b7f51b174a2ffa7 192.168.0.86:7002
slots:5461-10922 (5462 slots) master
M: 0bef99f8dc7853c47bc3a108a8082c290451caf1 192.168.0.86:7003
slots:10923-16383 (5461 slots) master
S: 31f95d284fb01e166469d6fd5096df480075d976 192.168.0.86:7004
replicates f49a220719ecfdb1e36cd14b3eeb7f4ac011c753
S: ddbd25b8c282bc33e8f35b18b1fe9a770b836e3c 192.168.0.86:7005
replicates 8bf30c7084cae9c9baca14b00b7f51b174a2ffa7
S: 726b60529e30c354b40db02dbfb505f55dd36ef2 192.168.0.86:7006
replicates 0bef99f8dc7853c47bc3a108a8082c290451caf1
Can I set the above configuration? (type 'yes' to accept): yes >>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join..
>>> Performing Cluster Check (using node 192.168.0.86:7001)
M: f49a220719ecfdb1e36cd14b3eeb7f4ac011c753 192.168.0.86:7001
slots:0-5460 (5461 slots) master #
M: 8bf30c7084cae9c9baca14b00b7f51b174a2ffa7 192.168.0.86:7002
slots:5461-10922 (5462 slots) master
M: 0bef99f8dc7853c47bc3a108a8082c290451caf1 192.168.0.86:7003
slots:10923-16383 (5461 slots) master
M: 31f95d284fb01e166469d6fd5096df480075d976 192.168.0.86:7004
slots: (0 slots) master
replicates f49a220719ecfdb1e36cd14b3eeb7f4ac011c753
M: ddbd25b8c282bc33e8f35b18b1fe9a770b836e3c 192.168.0.86:7005
slots: (0 slots) master
replicates 8bf30c7084cae9c9baca14b00b7f51b174a2ffa7
M: 726b60529e30c354b40db02dbfb505f55dd36ef2 192.168.0.86:7006
slots: (0 slots) master
replicates 0bef99f8dc7853c47bc3a108a8082c290451caf1
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
[root@node86 7001]# redis-cli -c -h 192.168.0.86 -p 7001
192.168.0.86:7001> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=7004,state=online,offset=449,lag=1
master_repl_offset:463
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:462 192.168.0.86:7001> set myclskey1 shanhgai
-> Redirected to slot [8385] located at 127.0.0.1:7002 转到7002
OK
127.0.0.1:7002> keys *
1) "myclskey1"
127.0.0.1:7002> set myclskey2 shenzhen
-> Redirected to slot [4258] located at 127.0.0.1:7001 转到7001
OK 127.0.0.1:7001>
127.0.0.1:7001> cluster nodes (cluster info)
31f95d284fb01e166469d6fd5096df480075d976 127.0.0.1:7004 slave f49a220719ecfdb1e36cd14b3eeb7f4ac011c753 0 1485773567359 4 connected
0bef99f8dc7853c47bc3a108a8082c290451caf1 127.0.0.1:7003 master - 0 1485773566852 3 connected 10923-16383
ddbd25b8c282bc33e8f35b18b1fe9a770b836e3c 127.0.0.1:7005 slave 8bf30c7084cae9c9baca14b00b7f51b174a2ffa7 0 1485773567863 5 connected
726b60529e30c354b40db02dbfb505f55dd36ef2 127.0.0.1:7006 slave 0bef99f8dc7853c47bc3a108a8082c290451caf1 0 1485773565842 6 connected
8bf30c7084cae9c9baca14b00b7f51b174a2ffa7 127.0.0.1:7002 master - 0 1485773567863 2 connected 5461-10922
f49a220719ecfdb1e36cd14b3eeb7f4ac011c753 192.168.0.86:7001 myself,master - 0 0 1 connected 0-5460
[root@node86 ~]# redis-trib add-node 192.168.0.86:7007 192.168.0.86:7001 新增一个节点 192.168.0.86:7001> cluster nodes
31f95d284fb01e166469d6fd5096df480075d976 127.0.0.1:7004 slave f49a220719ecfdb1e36cd14b3eeb7f4ac011c753 0 1485774184494 4 connected
314468099f6764df4065ce4712f64df2bdde47f0 127.0.0.1:7007 master - 0 1485774182978 0 connected
0bef99f8dc7853c47bc3a108a8082c290451caf1 127.0.0.1:7003 master - 0 1485774184998 3 connected 10923-16383
ddbd25b8c282bc33e8f35b18b1fe9a770b836e3c 127.0.0.1:7005 slave 8bf30c7084cae9c9baca14b00b7f51b174a2ffa7 0 1485774183481 5 connected
726b60529e30c354b40db02dbfb505f55dd36ef2 127.0.0.1:7006 slave 0bef99f8dc7853c47bc3a108a8082c290451caf1 0 1485774183986 6 connected
8bf30c7084cae9c9baca14b00b7f51b174a2ffa7 127.0.0.1:7002 master - 0 1485774184998 2 connected 5461-10922
f49a220719ecfdb1e36cd14b3eeb7f4ac011c753 192.168.0.86:7001 myself,master - 0 0 1 connected 0-5460 ..... 新加默认master新加未分配槽位,不会分数据, 新加默认master
#redis-trib reshard 192.168.0.86:7001 #重新分配槽位,应该只要是master 就可以,按提示操作 How many slots do you want to move (from 1 to 16384)? 2000
What is the receiving node ID? 314468099f6764df4065ce4712f64df2bdde47f0 7007的ID
Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.
Type 'done' once you entered all the source nodes IDs.
Source node #1:all
.....
Do you want to proceed with the proposed reshard plan (yes/no)? yes
.....
192.168.0.86:7001> cluster nodes
31f95d284fb01e166469d6fd5096df480075d976 127.0.0.1:7004 slave f49a220719ecfdb1e36cd14b3eeb7f4ac011c753 0 1485775128919 4 connected
314468099f6764df4065ce4712f64df2bdde47f0 127.0.0.1:7007 master - 0 1485775130934 7 connected 0-665 5461-6127 10923-11588 分配到不连续的2000个槽位
0bef99f8dc7853c47bc3a108a8082c290451caf1 127.0.0.1:7003 master - 0 1485775130934 3 connected 11589-16383
ddbd25b8c282bc33e8f35b18b1fe9a770b836e3c 127.0.0.1:7005 slave 8bf30c7084cae9c9baca14b00b7f51b174a2ffa7 0 1485775129927 5 connected
726b60529e30c354b40db02dbfb505f55dd36ef2 127.0.0.1:7006 slave 0bef99f8dc7853c47bc3a108a8082c290451caf1 0 1485775130429 6 connected
8bf30c7084cae9c9baca14b00b7f51b174a2ffa7 127.0.0.1:7002 master - 0 1485775129422 2 connected 6128-10922
f49a220719ecfdb1e36cd14b3eeb7f4ac011c753 192.168.0.86:7001 myself,master - 0 0 1 connected 666-5460
[root@node86 ~]# redis-trib add-node 192.168.0.86:7008 192.168.0.86:7001 再新增一个节点默认master [root@node86 ~]# redis-cli -h 192.168.0.86 -p 7008
192.168.0.86:7008> cluster replicate 314468099f6764df4065ce4712f64df2bdde47f0
OK
192.168.0.86:7008> cluster nodes
31f95d284fb01e166469d6fd5096df480075d976 127.0.0.1:7004 slave f49a220719ecfdb1e36cd14b3eeb7f4ac011c753 0 1485775364660 1 connected
314468099f6764df4065ce4712f64df2bdde47f0 127.0.0.1:7007 master - 0 1485775364155 7 connected 0-665 5461-6127 10923-11588
f49a220719ecfdb1e36cd14b3eeb7f4ac011c753 127.0.0.1:7001 master - 0 1485775366174 1 connected 666-5460
726b60529e30c354b40db02dbfb505f55dd36ef2 127.0.0.1:7006 slave 0bef99f8dc7853c47bc3a108a8082c290451caf1 0 1485775364660 3 connected
ddbd25b8c282bc33e8f35b18b1fe9a770b836e3c 127.0.0.1:7005 slave 8bf30c7084cae9c9baca14b00b7f51b174a2ffa7 0 1485775364155 2 connected
8bf30c7084cae9c9baca14b00b7f51b174a2ffa7 127.0.0.1:7002 master - 0 1485775366175 2 connected 6128-10922
b420cb9ff05cf1c4333c3fae5a9d1a8a7b1c6def 127.0.0.1:7008 myself,slave 314468099f6764df4065ce4712f64df2bdde47f0 0 0 0 connected
0bef99f8dc7853c47bc3a108a8082c290451caf1 127.0.0.1:7003 master - 0 1485775365163 3 connected 11589-16383
redis管理工具phpredisadmin
https://github.com/ErikDubbelboer/phpRedisAdmin # yum install httpd php php-redis php-mbstring #service httpd restart #yum install httpd php php-redis php-mbstring #service httpd start #cd /var/www/html/ #git clone https://github.com/ErikDubbelboer/phpRedisAdmin.git #cd phpRedisAdmin #git clone https://github.com/nrk/predis.git vendor #cd /var/www/html/phpRedisAdmin/includes/config.sample.inc.php #cp config.sample.inc.php config.inc.php #vi config.inc.php $config = array( 'servers' => array( array( 'name' => '7001', // Optional name. 'host' => '192.168.0.86', 'port' => 7001, 'filter' => '*', 'scheme' => 'tcp', // Optional. Connection scheme. 'tcp' - for TCP connection, 'unix' - for connection by unix domain socket 'path' => '' // Optional. Path to unix domain socket. Uses only if 'scheme' => 'unix'. Example: '/var/run/redis/redis.sock' // Optional Redis authentication. //'auth' => 'redispasswordhere' // Warning: The password is sent in plain-text to the Redis server. ), array( 'name' => '7002', 'host' => '192.168.0.86', 'port' => 7002 ), array( 'name' => '7003', 'host' => '192.168.0.86', 'port' => 7003 ),
rdbtools
分析redis内存,生产常用,生成内存报告 #wget https://github.com/sripathikrishnan/redis-rdb-tools/archive/master.zip #unzip master.zip #cd redis-rdb-tools-master/ #python setup.py install # rdb -c memory /redisfile/7001/dump.rdb > memory7001.csv