Overview of Redis
The word Redis means Remote DIctionary Server
Initial release in 2009
It is an advanced key-value store or a data structure store
Runs entirely in memory
All data is kept in memory
Quick data access since it is maintained in memory
Data can be backed up to disk periodically
Single threaded server
Extensible via Lua scripts
Able to replicate data between servers
Clustering also available

About Redis
"Redis is an open source, BSD licensed, advanced key-value cache and store. It is oftenreferred to as a data structure server since keys can contain strings, hashs, lists, sets, sorted sets, bitmaps and hyperloglogs."

Redis:
KV cache and store
in-memory
持久化
主从(借助于sentinel实现一定意义上的HA)
Clustering(分布式)

    数据结构服务器:
        String, List, Hash, Set, Sorted Set, Bitmap, HyperLoglog

Redis
Redis is an in-memory but persistent on disk database
1 Million small key --> String value pairs use ~ 100MB of memory
Single threaded - but CPU should not be the bottleneck
Average Linux system can deliver even 500k requests per second
Limit is likely the available memory in your system
max. 232 keys

Persistence
Snapshotting
Data is asynchronously thransferred from memory to disk
AOF(Append Only File)
Each medifying operation is written to a file
Can recreate data store by replaying operations
Without interrupting service, will rebuild AOF as the shortest sequence of commands neded to rebuild the current dataset in memory

Replication
Redis supports master-slave replication
Master-slave replication can be chained
Be careful:
Slaves are writeable!
Potential for data inconsistency
Fully compatible with Pub/Sub features

Differences to Memcached
Memcached is a "distributed memory object caching system"
Redis persists data to disk eventually
Memcached is an LRU cache
Redis has different data types and more features
Memcached is multithreaded
Similar speed

Redis的优势
丰富的(资料形态)操作
Hashs, Lists, Sets, Sorted Sets, HyperLoglog等
内建replication及cluster
就地更新(in-place update)操作
支持持久化(磁盘)
避免雪崩效应
Memcached的优势
多线程
善用多核CPU
更少的阻塞操作
更少的内存开销
更少的内存分配压力
可能有更少的内存碎片

Prominent Adopters
Twitter
Pinterest
Tumblr
GitHub
Stack Overflow
digg
Blizard
flickr
WeiBo
... ...

Redis 3.0
2015年4月1日正式推出
Redis Cluster
新的"embedded string"
LRU演算法的改进
预设随机取5个样本,插入并排序至一个pool,移除最佳者,如此反复,直到内存用量小于maxmemory的设定
样本5比先前的3多
从局部最优趋向全局最优

Redis特性
BDBMS
Oracle, DB2, PostgreSQL, MySQL, SQL Server, ...
NoSQL
Cassandra, HBase, Memcached, MongoDB, Redis, ...
NewSQL
Aerospike, FoundationDB, RethinkDB, ...

存储系统有三类:
RDBMS:关系型数据库
NoSQL:非关系型数据库
KV NoSQL:redis
Colum Family NoSQL:HBase
Documention NoSQL:MongoDB
Graph NoSQL:Neo4j
NewSQL:分布式关系型数据库

Redis特性
Key-value NoSQL
Memcached, Redis, ...
Column family NoSQL
Cassandra, HBase, ...
Documen NoSQL
MongoDB, ...
Graph NoSQL
Neo4j, ...

Commands
Redis-server
redis-cli
Command line interface
Redis-benchmark
Benchmarking utility
redis-check-dump & redis-check-aof
Corrupted RDB/AOF files utilities

Redis的组件:
redis.io

Overview
Family of fundamental data structures
Strings and string containers
Accessed / indexed by key
Directly exposed -- No abstraction layers
Rich set of atomic operations over the structures
Detailed reference using big-O notation for complexities
Basic publish / subscribe infrastructure

官方站点:www.redis.io

Redis守护进程:
监听端口:6379/tcp

Keys
Arbitrary ASCII strings
Define some format convention and adhere to it
Key length matters!
Multiple name spaces are available
Separate DBs indexed by an integer value
SELECT command
Multiples DBs vs. Single DB + key prefixes
Keys can expire automatically

Data structures
Strings
Caching, counters, realtime metrice...
Hashes
"Object" storage...
Lists
Logs, queues, message passing...
Sets
Membership, tracking...
Ordered sets
Leaderboards, activity feeds...

Strings
help @string
SET
GET
EXISTS
Integers
DECR
INCR

String:
SET key value [EX #] [NX|XX]
GET
INCR
DECR
EXIST

Advanced Data Structures
redis_第1张图片

Lists
help @list
RPUSH
LPUSH
LPOP
RPOP

Lists:
LPUSH
RPUSH
LPOP
RPOP
LINDEX
LSET

Sets
help @set
SADD
SMEMBERS
SINTER

Sets:
SADD
SINTER
SUNION
SPOP
SISMEMBER

Sorted Sets
help @sorted_set
ZADD
ZSCORE
ZRANGE
ZRANGEBYSCORE

Sorted Sets:
ZADD
ZRANGE
ZCARD
ZRANK

Hashes
help @hash
HSET
HGET
HGETALL

Hashes:
HSET
HSETNX
HKEYS
HVALS
HDEL

Bitmaps, HyperLogLog

认证实现方法:
(1) redis.conf
requirepass PASSWORD
(2) redis-cli
AUTH PASSWORD

清空数据库:
FLUSHDB:清空当前库
FLUSHALL:清空所有库

事务:
通过MULTI, EXEC, WATCH等命令实现事务功能:将一个或多个命令归并为一个操作提请服务器按顺序执行的机制,不支持回滚操作;

    MULTI:启动一个事务;
    EXEC:执行事务;
        一次性将事务中的所有操作执行完成后返回给客户端;
    WATCH:乐观锁:在EXEC命令执行之前,用于监视指定数量键,如果监视中的某任意键数据被修改,则服务器拒绝执行事务;

Connection相关命令:
AUTH:认证相关
ECHO
PING
QUIT
SELECT

Server相关的命令:
CLIENT SETNAME connection-name:设置当前连接名称
CLIENT GETNAME:获取当前client连接名;
CLIENT KILL ip:port:踢掉客户端;

    CONFIG GET
    CONFIG RESETSTAT:重启状态信息
CONFIG SET parameter value:运行中修改某参数的值;
    CONFIG REVRITE:将修改在内存中的参数的值写入配置文件;

DESIZE:显示数据库中键的数量;

BGSAVE
SAVE
LASTSAVE:获取最近一次将数据保存到磁盘的时间戳

    MONITOR:事实监控所接收到的请求;

SHUTDOWN:将数据同步到磁盘安全关闭;

SLAVEOF host port:配置主从

SHOWLOG:显示慢查询日志;

    TIME:返回当前时间;

SYNC:复制功能内建命令;

发布与订阅(publish/subscribe)
频道:消息队列

    SUBSCRIBE:订阅一个或多个队列;
PUBLISH:向频道发布消息;

UNSUBSCRIBE:退订此前订阅的频道;

PSUBSCRIBE:模式订阅

Redis的持久化:
RDB和AOF
RDB:snapshot,二进制格式,按事先定制的策略,周期性地将数据保存至磁盘,默认数据文件为dump.rdb;
客户端也可以显示使用SAVE或BGSAVE命令启动快照保存机制;
SAVE:同步,在主线程中保存快照,此时会阻塞所有客户端请求;
BGSAVE:异步,
AOF:Append Only File
记录每一次写操作至指定的文件尾部实现持久化,当redis重启时,可通过重新执行文件中的命令在内存中重建数据库
BGREWRITEAOF:AOF文件重写
不会读取正在使用AOF文件,而通过将内存中的数据以命令的方式保存到临时文件中,完成之后替换原来的AOF文件;

    RDB:
                SAVE 900 1
                    SAVE 300 10
                    SAVE 60 10000

        stop-write-on-bgsave-error yes
                    rdbcompression ye
                    rdbchecksum dump.rdb
                    dir /var/lib/redis

            AOF:
                重写过程:
                        (1) redis主进程通过fork创建子进程;
                            (2) 子进程根据redis内存中的数据创建数据库重建命令序列于临时文件中;
                            (3) 父进程继承client的请求,并会把这些请求中的写操作继续追加至原来AOF文件,额外的这些新的写请求还会被置于一个缓存队列中;
                            (4) 子进程重写完成,会通知父进程,父进程把缓冲中的命令写到临时文件中
                            (5) 父进程用临时文件替换老的aof文件;

                    相关参数:
            appendonly no
                            appendfilename "appendonly.aof"
                            appendfsync (always|everysec|no)
                            no-appendfsync-on-rewrite no
                            auto-aof-rewrite-percentage 100
                            auto-aof-rewrite-min-size 64mb

                注意:持久本身不能取代备份,还应该制定备份策略,对redis数据库定期进行备份;

        RDB与AOF同时启用:
            (1) BGSAVE和GBREWRITEAOF不会同时执行;
                (2) 在Redis服务器启动用于恢复数据时,会优先使用AOF;

复制:
特点:
一个Master可以有多个Slave;
支持链式复制;
Master以非阻塞方式同步数据至slave;

    slave:
        > SLAVAOF MASTER_IP MASTER_PORT

  注意:如果master使用requirepass开启了认证功能,从服务器要使用masterauth 来连入服务器请求此密码进行认证;

sentinel:
用于管理多个redis服务实现HA;
监控多个服务器节点
通知
自动故障转移

            流言协议,投票协议

    程序:
        redis-ssentinel /path/to/file.conf
            redis-server /path/to/file.conf --sentinel

    (1) 服务器自身初始化,运行redis-server中专用于sentinel功能的代码;
            (2) 初始化sentinel状态,根据给定的配置文件,初始化监控的master服务器列表;
            (3) 创建连向master的连接;

    专用配置文件:  /etc/redis-sentinel.conf
        (1)# sentinel monitor    

            sentinel monitor mymaster 127.0.0.1 6379 2
            (2) sentinel down-after-milliseconds  

        sentinel down-after-milliseconds mymaster 30000

    (3) sentinel parallel-syncs  

                sentinel parallel-syncs mymaster 1

            (4) sentinel failover-timeout  

        sentinel failover-timeout mymaster 180000

主观下线,客观下线:
        主观下线:一个sentine实例判断出其节点下线;
            客观下线:多个sentine节点协商后判断出某节点下线;

专用命令:
    SENTINEL masters
            SENTINEL slaves 
            SENTINEL get-master-addr-by-name 
            SENTINEL reset
            SENTINEL failover 

Clustering:
分布式数据库,通过分片机制来进行数据分布,clustering内的每个节点仅数据库的一部分数据;
每个节点持有全局元数据,但仅持有一部分数据;

Avalibility
Twemproxy(Twitter)
Codis(豌豆荚)
Redis Cluster(官方)
Cerberus(芒果TV)

Avalibility
Twemproxy(Twitter)
代理分片机制
优点
非常稳定,企业级方案
缺点
单点故障
需依赖第三方软件,如Keepalived
无法平滑地横向扩展
没有后台界面
代理分片机制引入更多的来回次数并提高延迟
单核模式,无法充分利用多核,除非多实例
Twitter官方不再继续使用Twemproxy

Avalibility
Codis(豌豆荚)
代理分片机制
2014年11月开源
基于Go以及C语言开发
优点
非常稳定,企业级方案
数据自动平衡
高性能
简单的测试显示较wemproxy快一倍
善用多核CPU
简单
没有Paxos类的协调机制
没有主从复制
有后台界面
缺点
代理分片机制引入更多的来回次数并提高延迟
需要第三方软件支持协调机制
目前支持Zookeeper及Etcd
不支持主从复制,需要另外实现
Codis采用了Proxy的方案,所以必然会带来单机性能的损失
经测试,在不开pipeline的情况下,大概会损失40%左右的性能

Avalibility
Redis Cluster(官方)
官方实现
需要Redis 3.0或更高版本
优点
无中心的P2P Gossip分散式模式
更少的来回次数降低延迟
自动于多个Redis节点进行分片
不需要第三方软件支持协调机制
缺点
依赖于Redis 3.0或更高版本
需要时间验证其稳定性
没有后台界面
需要智能客户端
Redis客户端必须支持Redis Cluster架构
较Codis有更多的维护升级成本

Avalibility
Cerberus(芒果TV)
优点
数据自动平衡
本身实现了Redis的Smart Client
支持读写分离
缺点
依赖Redis 3.0或更高版本
代理分片机制引入更多的来回次数并增大延迟
需要时间验证其稳定性
没有后台界面

实验环境:
主机1
系统版本:Centos6.5
内核版本:2.6.32-504.el6.x86_64
网卡1:VMnet0 172.16.100.6
网卡2:VMnet8 NAT DHCP
主机2
系统版本:Centos6.5
内核版本:2.6.32-504.el6.x86_64
网卡1:VMnet0 172.16.100.6
网卡2:VMnet8 NAT DHCP

主机1:

[root@CentOS6 ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo
[root@CentOS6 ~]# yum info redis
Loaded plugins: fastestmirror, security
Loading mirror speeds from cached hostfile
 * base: mirrors.aliyun.com
 * extras: mirrors.aliyun.com
 * updates: mirrors.aliyun.com
Available Packages
Name        : redis
Arch        : x86_64
Version     : 3.2.12
Release     : 2.el6
Size        : 522 k
Repo        : epel
Summary     : A persistent key-value database
URL         : http://redis.io
License     : BSD
Description : Redis is an advanced key-value store. It is often referred to as a data
            : structure server since keys can contain strings, hashes, lists, sets and
            : sorted sets.
            :
            : You can run atomic operations on these types, like appending to a string;
            : incrementing the value in a hash; pushing to a list; computing set
            : intersection, union and difference; or getting the member with highest
            : ranking in a sorted set.
            :
            : In order to achieve its outstanding performance, Redis works with an
            : in-memory dataset. Depending on your use case, you can persist it either
            : by dumping the dataset to disk every once in a while, or by appending
            : each command to a log.
            :
            : Redis also supports trivial-to-setup master-slave replication, with very
            : fast non-blocking first synchronization, auto-reconnection on net split
            : and so forth.
            :
            : Other features include Transactions, Pub/Sub, Lua scripting, Keys with a
            : limited time-to-live, and configuration settings to make Redis behave like
            : a cache.
            :
            : You can use Redis from most programming languages also.
[root@CentOS6 ~]# yum -y install redis
[root@CentOS6 ~]# cp /etc/redis.conf{,.orgi}
[root@CentOS6 ~]# vim /etc/redis.conf
bind 127.0.0.1 172.16.100.6
[root@CentOS6 ~]# service redis start
[root@CentOS6 ~]# ss -tnl
State       Recv-Q Send-Q                                 Local Address:Port                                   Peer Address:Port
LISTEN      0      128                                               :::22                                               :::*
LISTEN      0      128                                                *:22                                                *:*
LISTEN      0      128                                        127.0.0.1:6379                                              *:*
[root@CentOS6 ~]# redis-cli -h 172.16.100.6
172.16.100.6:6379> help

172.16.100.6:6379> help @STRING

172.16.100.6:6379> HELP APPEND

172.16.100.6:6379> CLIENT LIST    #查看连接客户端
id=2 addr=172.16.100.6:59420 fd=6 name= age=228 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=client

172.16.100.6:6379> SELECT 1    #打开1号数据库,默认16个数据库

172.16.100.6:6379[1]> SELECT 0    #默认为0号数据库

172.16.100.6: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

172.16.100.6:6379> SET disto fedora
OK
172.16.100.6:6379> GET disto
"fedora"
172.16.100.6:6379> SET disto centos
OK
172.16.100.6:6379> append disto slackware
(integer) 15
172.16.100.6:6379> GET disto
"centosslackware"
172.16.100.6:6379> STRLEN disto
(integer) 15
172.16.100.6:6379> SET count 0
OK
172.16.100.6:6379> INCR count
(integer) 1
172.16.100.6:6379> INCR count
(integer) 2
172.16.100.6:6379> DECR count
(integer) 1
172.16.100.6:6379> DECR count
(integer) 0
172.16.100.6:6379> SET disto gentoo NX
(nil)    #未能执行操作
172.16.100.6:6379> GET disto
"centosslackware"    #键不存在时才设置新值
172.16.100.6:6379> SET foo bar XX    #键存在才设置新值
(nil)
172.16.100.6:6379> set foo bar
OK
172.16.100.6:6379> incr foo    #只能对整数值操作
(error) ERR value is not an integer or out of range

172.16.100.6:6379> HELP @LIST

172.16.100.6:6379> LPUSH l1 mon
(integer) 1
172.16.100.6:6379> LINDEX l1 0
"mon"
172.16.100.6:6379> LPUSH l1 sun
(integer) 2
172.16.100.6:6379> LINDEX l1 0
"sun"
172.16.100.6:6379> RPUSH l1 tue
(integer) 3
172.16.100.6:6379> LINDEX l1 2
"tue"
172.16.100.6:6379> LSET l1 1 fri
OK
172.16.100.6:6379> LINDEX l1 1
"fri"
172.16.100.6:6379> RPOP l1
"tue"
172.16.100.6:6379> RPOP l1
"fri"
172.16.100.6:6379> RPOP l1
"sun"
172.16.100.6:6379> RPOP l1
(nil)

172.16.100.6:6379> HELP @SET

172.16.100.6:6379> SADD w1 mon tue wed thu fre sat sun
(integer) 7
172.16.100.6:6379> SADD w2 tue thu day
(integer) 3
172.16.100.6:6379> SINTER w1 w2
1) "thu"
2) "tue"
172.16.100.6:6379> SUNION w1 w2
1) "wed"
2) "tue"
3) "thu"
4) "day"
5) "mon"
6) "sun"
7) "fre"
8) "sat"
172.16.100.6:6379> SPOP w1
"mon"
172.16.100.6:6379> SPOP w1
"wed"
172.16.100.6:6379> SISMEMBER w1 wed
(integer) 0
172.16.100.6:6379> SISMEMBER w1 tue
(integer) 1    #1代表元素存在

172.16.100.6:6379> HELP @SORTED_SET

172.16.100.6:6379> ZADD weekday1 1 mon 2 tue 3 wed
(integer) 3
172.16.100.6:6379> ZCARD weekday1
(integer) 3
172.16.100.6:6379> ZRANK weekday1 tue
(integer) 1
172.16.100.6:6379> ZRANK weekday1 wed
(integer) 2
172.16.100.6:6379> ZRANK weekday1 mon
(integer) 0
172.16.100.6:6379> ZSCORE weekday1 tue
"2"
172.16.100.6:6379> ZRANGE weekday1 0 2
1) "mon"
2) "tue"
3) "wed"
172.16.100.6:6379> ZRANGE weekday1 0 1
1) "mon"
2) "tue"

172.16.100.6:6379> HELP @HASH

172.16.100.6:6379> HSET h1 a mon
(integer) 1
172.16.100.6:6379> HGET h1 a
"mon"
172.16.100.6:6379> HSET h1 b tue
(integer) 1
172.16.100.6:6379> HGET h1 a
"mon"
172.16.100.6:6379> HGET h1 b
"tue"
172.16.100.6:6379> HKEYS h1
1) "a"
2) "b"
172.16.100.6:6379> HVALS h1
1) "mon"
2) "tue"
172.16.100.6:6379> HLEN h1
(integer) 2

[root@CentOS6 ~]# vim /etc/redis.conf
requirepass smoke520    #启用密码
[root@CentOS6 ~]# service redis restart

[root@CentOS6 ~]# redis-cli -h 172.16.100.6
172.16.100.6:6379> SELECT 0
(error) NOAUTH Authentication required.
172.16.100.6:6379> AUTH smoke520    #认证
OK
172.16.100.6:6379> SELECT 0
OK

[root@CentOS6 ~]# redis-cli -h 172.16.100.6
172.16.100.6:6379> FLUSHDB
OK
172.16.100.6:6379> MULTI    #执行事务
OK
172.16.100.6:6379> SET ip 192.168.1.1
QUEUED
172.16.100.6:6379> SET port 8080
QUEUED
172.16.100.6:6379> GET port
QUEUED
172.16.100.6:6379> EXEC
1) OK
2) "192.168.1.1"
3) OK
4) "8080"
172.16.100.6:6379> WATCH ip
OK

打开一个新的终端连接redis;

[root@CentOS6 ~]# redis-cli
127.0.0.1:6379> GET ip
"192.168.1.1"
127.0.0.1:6379> SET ip 172.16.100.99
OK
127.0.0.1:6379>

在原来的终端连接的redis;

172.16.100.6:6379> EXEC
(nil)    #事务执行失败;
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> GET ip
QUEUED
127.0.0.1:6379> SET port 5379
QUEUED
127.0.0.1:6379> SETTTT
(error) ERR unknown command 'SETTTT'
127.0.0.1:6379> EXEC
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> HELP PING

128.127.0.0.1:6379> PING
PONG
127.0.0.1:6379> help ECHO

  ECHO message
  summary: Echo the given string
  since: 1.0.0
  group: connection
127.0.0.1:6379> ECHO "hello redis"
"hello redis"
127.0.0.1:6379> HELP @connection
127.0.0.1:6379> help @server
127.0.0.1:6379> CLIENT GETNAME
(nil)
127.0.0.1:6379> CLIENT SETNAME localconn
OK
127.0.0.1:6379> CLIENT GETNAME
"localconn"
127.0.0.1:6379> HELP INFO
127.0.0.1:6379> INFO    #获取服务器配置信息
# Server
redis_version:3.2.12
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:b2d74fe5fff7657d
redis_mode:standalone
os:Linux 2.6.32-504.el6.x86_64 x86_64
arch_bits:64
multiplexing_api:epoll
gcc_version:4.4.7
process_id:33383
run_id:7b7fe366481f4c2bcc3cf3f0b4395ed8b65a7abd
tcp_port:6379
uptime_in_seconds:11849
uptime_in_days:0
hz:10
lru_clock:3706298
executable:/usr/bin/redis-server
config_file:/etc/redis.conf

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

# Memory
used_memory:854480
used_memory_human:834.45K
used_memory_rss:5447680
used_memory_rss_human:5.20M
used_memory_peak:854824
used_memory_peak_human:834.79K
total_system_memory:1952243712
total_system_memory_human:1.82G
used_memory_lua:37888
used_memory_lua_human:37.00K
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
mem_fragmentation_ratio:6.38
mem_allocator:jemalloc-3.6.0

# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1563976945
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:3
total_commands_processed:22
instantaneous_ops_per_sec:0
total_net_input_bytes:644
total_net_output_bytes:30094
instantaneous_input_kbps:0.00
instantaneous_output_kbps:0.00
rejected_connections:0
sync_full:0
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:2020
migrate_cached_sockets:0

# Replication
role:master
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

# CPU
used_cpu_sys:15.04
used_cpu_user:7.74
used_cpu_sys_children:0.57
used_cpu_user_children:0.00

# Cluster
cluster_enabled:0

# Keyspace
db0:keys=2,expires=0,avg_ttl=0
127.0.0.1:6379> DBSIZE
(integer) 2
127.0.0.1:6379> monitor
OK    #使用quit退出;
127.0.0.1:6379> HELP SUBSCRIBE
127.0.0.1:6379> help @pubsub
127.0.0.1:6379> SUBSCRIBE news    #订阅消息
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "news"
3) (integer) 1

打开一个新的终端连接redis;

127.0.0.1:6379> PUBLISH news hello
(integer) 1

在原来的终端查看;

127.0.0.1:6379> SUBSCRIBE news
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "news"
3) (integer) 1
1) "message"
2) "news"
3) "hello"

继续发送;

127.0.0.1:6379> PUBLISH news redis
(integer) 1

在原来的终端查看;

127.0.0.1:6379> SUBSCRIBE news
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "news"
3) (integer) 1
1) "message"
2) "news"
3) "hello"
1) "message"
2) "news"
3) "redis"
[root@CentOS6 ~]# redis-cli
127.0.0.1:6379> PSUBSCRIBE "news.i[to]"    #订阅多个频道
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "news.i[to]"
3) (integer) 1
1) "pmessage"
2) "news.i[to]"
3) "news.io"
4) "hello"

打开一个新的终端连接redis;

127.0.0.1:6379> PUBLISH news.io hello
(integer) 1

在原来的终端查看;

127.0.0.1:6379> PSUBSCRIBE "news.i[to]"
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "news.i[to]"
3) (integer) 1
1) "pmessage"
2) "news.i[to]"
3) "news.io"
4) "hello"

继续发送;

127.0.0.1:6379> PUBLISH news.it redis
(integer) 1

在原来的终端查看;

127.0.0.1:6379> PSUBSCRIBE "news.i[to]"
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "news.i[to]"
3) (integer) 1
1) "pmessage"
2) "news.i[to]"
3) "news.io"
4) "hello"
1) "pmessage"
2) "news.i[to]"
3) "news.it"
4) "redis"

在新的终端;

127.0.0.1:6379> CONFIG GET dir
1) "dir"
2) "/var/lib/redis"
127.0.0.1:6379> CONFIG SET appendonly yes
OK

复制:
主机2:

[root@CentOS6 ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo
[root@CentOS6 ~]# yum -y install redis
[root@CentOS6 ~]# service redis start
[root@CentOS6 ~]# vim /etc/redis.conf
bind 127.0.0.1 172.16.100.7
[root@CentOS6 ~]# redis-cli
127.0.0.1:6379> SLAVEOF 172.16.100.6 6379    #指定自己为从服务器;
OK
127.0.0.1:6379> GET ip
"172.16.100.99"
127.0.0.1:6379> GET port
"8080"
127.0.0.1:6379> INFO REPLICATIOn
# Replication
role:slave
master_host:172.16.100.6
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:1835
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
127.0.0.1:6379> KEYS *
1) "ip"
2) "port"

主机2:

[root@CentOS6 ~]# vim /etc/redis-sentinel.conf
[root@CentOS6 ~]# killall redis-server
[root@CentOS6 ~]# mkdir /etc/redis -pv
[root@CentOS6 ~]# cp /etc/redis.conf /etc/redis
[root@CentOS6 ~]# cd /etc/redis
[root@CentOS6 redis]# cp redis.conf redis.conf.2
[root@CentOS6 redis]# cp redis.conf redis.conf.3
[root@CentOS6 redis]# mkdir -pv /redis/db{1,2,3}
[root@CentOS6 redis]# chown -R redis.redis /redis/db*
[root@CentOS6 redis]# vim redis.conf
bind 0.0.0.0
logfile /var/log/redis/redis.log
pidfile /var/run/redis_6379.pid
dir /redis/db1
daemonize yes
[root@CentOS6 redis]# vim redis.conf.2
port 6380
pidfile /var/run/redis_6380.pid
logfile /var/log/redis/redis2.log
dir /redis/db2
bind 0.0.0.0
daemonize yes
[root@CentOS6 redis]# vim redis.conf.3
port 6381
pidfile /var/run/redis_6381.pid
logfile /var/log/redis/redis3.log
dir /redis/db3
bind 0.0.0.0
daemonize yes
[root@CentOS6 redis]# redis-server /etc/redis/redis.conf
[root@CentOS6 redis]# redis-server /etc/redis/redis.conf.2
[root@CentOS6 redis]# redis-server /etc/redis/redis.conf.3
[root@CentOS6 redis]# ss -tnl
State      Recv-Q Send-Q                    Local Address:Port                      Peer Address:Port
LISTEN     0      128                                  :::22                                  :::*
LISTEN     0      128                                   *:22                                   *:*
LISTEN     0      128                                   *:6379                                 *:*
LISTEN     0      128                                   *:6380                                 *:*
LISTEN     0      128                                   *:6381                                 *:*

连接6379端口的redis-server:

[root@CentOS6 redis]# redis-cli -h 172.16.100.7 -p 6379
172.16.100.7:6379> info replication
# Replication
role:master
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

连接6380端口的redis-server:

[root@CentOS6 ~]# redis-cli -h 172.16.100.7 -p 6380
172.16.100.7:6380> info replication
# Replication
role:master
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
172.16.100.7:6380> slaveof 172.16.100.7 6379
OK
172.16.100.7:6380> info replication
# Replication
role:slave
master_host:172.16.100.7
master_port:6379
master_link_status:up
master_last_io_seconds_ago:5
master_sync_in_progress:0
slave_repl_offset:15
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

在6379端口的redis-server:

172.16.100.7:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=172.16.100.7,port=6380,state=online,offset=57,lag=1
master_repl_offset:57
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:56

连接6381端口的redis-server:

[root@CentOS6 ~]# redis-cli -h 172.16.100.7 -p 6381
172.16.100.7:6381> slaveof 172.16.100.7 6379
OK
172.16.100.7:6381> info replication
# Replication
role:slave
master_host:172.16.100.7
master_port:6379
master_link_status:up
master_last_io_seconds_ago:5
master_sync_in_progress:0
slave_repl_offset:127
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

在6379端口的redis-server:

172.16.100.7:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=172.16.100.7,port=6380,state=online,offset=169,lag=0
slave1:ip=172.16.100.7,port=6381,state=online,offset=169,lag=1
master_repl_offset:169
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:168
172.16.100.7:6379> SET ip 1.1.1.1
OK
172.16.100.7:6379> SET cache varnish
OK
172.16.100.7:6379> keys *
1) "ip"
2) "cache"

在6380端口的redis-server:

172.16.100.7:6380> keys *
1) "cache"
2) "ip"

在6381端口的redis-server:

172.16.100.7:6381> keys *
1) "ip"
2) "cache"

监控主节点:

[root@CentOS6 ~]# cp /etc/redis-sentinel.conf /etc/redis/
[root@CentOS6 ~]# cd /etc/redis
[root@CentOS6 redis]# vim redis-sentinel.conf
port 26379
logfile /var/log/redis/sentinel.log
dir /tmp
sentinel monitor mymaster 172.16.100.7 6379 1
sentinel down-after-milliseconds mymaster 5000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 60000
bind 0.0.0.0
[root@CentOS6 redis]# redis-sentinel /etc/redis/redis-sentinel.conf

连接26379端口的redis-sentinel:

[root@CentOS6 ~]# ss -tnl
State      Recv-Q Send-Q                    Local Address:Port                      Peer Address:Port
LISTEN     0      128                                  :::22                                  :::*
LISTEN     0      128                                   *:22                                   *:*
LISTEN     0      128                                   *:26379                                *:*
LISTEN     0      128                                  :::26379                               :::*
LISTEN     0      128                                   *:6379                                 *:*
LISTEN     0      128                                   *:6380                                 *:*
LISTEN     0      128                                   *:6381                                 *:*
[root@CentOS6 ~]# redis-cli -h 172.16.100.7 -p 26379
172.16.100.7:26379> info
# Server
redis_version:3.2.12
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:b2d74fe5fff7657d
redis_mode:sentinel
os:Linux 2.6.32-504.el6.x86_64 x86_64
arch_bits:64
multiplexing_api:epoll
gcc_version:4.4.7
process_id:31045
run_id:128bbf29c7cea429ef1f3855b616f638904fa57f
tcp_port:26379
uptime_in_seconds:7
uptime_in_days:0
hz:14
lru_clock:4090622
executable:/etc/redis/redis-sentinel
config_file:/etc/redis/redis-sentinel.conf

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

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

# Stats
total_connections_received:1
total_commands_processed:0
instantaneous_ops_per_sec:0
total_net_input_bytes:31
total_net_output_bytes:32
instantaneous_input_kbps:0.00
instantaneous_output_kbps:0.00
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
evicted_keys:0
keyspace_hits:0
keyspace_misses:0
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:0
migrate_cached_sockets: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=172.16.100.7:6379,slaves=2,sentinels=1
172.16.100.7:26379> SENTINEL masters
1)  1) "name"
    2) "mymaster"
    3) "ip"
    4) "172.16.100.7"
    5) "port"
    6) "6379"
    7) "runid"
    8) "096a1939b79c9bd803d9633e11d6516a85625ebb"
    9) "flags"
   10) "master"
   11) "link-pending-commands"
   12) "0"
   13) "link-refcount"
   14) "1"
   15) "last-ping-sent"
   16) "0"
   17) "last-ok-ping-reply"
   18) "610"
   19) "last-ping-reply"
   20) "610"
   21) "down-after-milliseconds"
   22) "5000"
   23) "info-refresh"
   24) "2236"
   25) "role-reported"
   26) "master"
   27) "role-reported-time"
   28) "72556"
   29) "config-epoch"
   30) "0"
   31) "num-slaves"
   32) "2"
   33) "num-other-sentinels"
   34) "0"
   35) "quorum"
   36) "1"
   37) "failover-timeout"
   38) "60000"
   39) "parallel-syncs"
   40) "1"
172.16.100.7:26379> SENTINEL slaves mymaster
1)  1) "name"
    2) "172.16.100.7:6380"
    3) "ip"
    4) "172.16.100.7"
    5) "port"
    6) "6380"
    7) "runid"
    8) "571935cca7848d99e41b3c68a6679f45a0e8daea"
    9) "flags"
   10) "slave"
   11) "link-pending-commands"
   12) "0"
   13) "link-refcount"
   14) "1"
   15) "last-ping-sent"
   16) "0"
   17) "last-ok-ping-reply"
   18) "90"
   19) "last-ping-reply"
   20) "90"
   21) "down-after-milliseconds"
   22) "5000"
   23) "info-refresh"
   24) "2429"
   25) "role-reported"
   26) "slave"
   27) "role-reported-time"
   28) "153075"
   29) "master-link-down-time"
   30) "0"
   31) "master-link-status"
   32) "ok"
   33) "master-host"
   34) "172.16.100.7"
   35) "master-port"
   36) "6379"
   37) "slave-priority"
   38) "100"
   39) "slave-repl-offset"
   40) "37447"
2)  1) "name"
    2) "172.16.100.7:6381"
    3) "ip"
    4) "172.16.100.7"
    5) "port"
    6) "6381"
    7) "runid"
    8) "5cd9e09389a83c04046ab7f6c42b21be55586afa"
    9) "flags"
   10) "slave"
   11) "link-pending-commands"
   12) "0"
   13) "link-refcount"
   14) "1"
   15) "last-ping-sent"
   16) "0"
   17) "last-ok-ping-reply"
   18) "90"
   19) "last-ping-reply"
   20) "90"
   21) "down-after-milliseconds"
   22) "5000"
   23) "info-refresh"
   24) "2429"
   25) "role-reported"
   26) "slave"
   27) "role-reported-time"
   28) "153075"
   29) "master-link-down-time"
   30) "0"
   31) "master-link-status"
   32) "ok"
   33) "master-host"
   34) "172.16.100.7"
   35) "master-port"
   36) "6379"
   37) "slave-priority"
   38) "100"
   39) "slave-repl-offset"
   40) "37447"

下线主节点:

[root@CentOS6 ~]# ps aux | grep redis-server
root      30769  0.1  0.3 139512  7384 ?        Ssl  11:09   0:03 redis-server 0.0.0.0:6379
root      30773  0.1  0.2 139512  5340 ?        Ssl  11:09   0:02 redis-server 0.0.0.0:6380         
root      30777  0.1  0.2 139512  5336 ?        Ssl  11:09   0:02 redis-server 0.0.0.0:6381         
root      31080  0.0  0.0 103256   840 pts/0    S+   11:48   0:00 grep redis-server
[root@CentOS6 ~]# kill 30769

在26379端口的redis-sentinel:

172.16.100.7:26379> info
# Server
redis_version:3.2.12
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:b2d74fe5fff7657d
redis_mode:sentinel
os:Linux 2.6.32-504.el6.x86_64 x86_64
arch_bits:64
multiplexing_api:epoll
gcc_version:4.4.7
process_id:31045
run_id:128bbf29c7cea429ef1f3855b616f638904fa57f
tcp_port:26379
uptime_in_seconds:548
uptime_in_days:0
hz:14
lru_clock:4091163
executable:/etc/redis/redis-sentinel
config_file:/etc/redis/redis-sentinel.conf

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

# CPU
used_cpu_sys:1.50
used_cpu_user:0.21
used_cpu_sys_children:0.00
used_cpu_user_children:0.00

# Stats
total_connections_received:1
total_commands_processed:6
instantaneous_ops_per_sec:0
total_net_input_bytes:216
total_net_output_bytes:3446
instantaneous_input_kbps:0.00
instantaneous_output_kbps:0.00
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
evicted_keys:0
keyspace_hits:0
keyspace_misses:0
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:0
migrate_cached_sockets: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=172.16.100.7:6380,slaves=2,sentinels=1
172.16.100.7:26379> SENTINEL masters
1)  1) "name"
    2) "mymaster"
    3) "ip"
    4) "172.16.100.7"
    5) "port"
    6) "6380"
    7) "runid"
    8) "571935cca7848d99e41b3c68a6679f45a0e8daea"
    9) "flags"
   10) "master"
   11) "link-pending-commands"
   12) "0"
   13) "link-refcount"
   14) "1"
   15) "last-ping-sent"
   16) "0"
   17) "last-ok-ping-reply"
   18) "110"
   19) "last-ping-reply"
   20) "110"
   21) "down-after-milliseconds"
   22) "5000"
   23) "info-refresh"
   24) "5188"
   25) "role-reported"
   26) "master"
   27) "role-reported-time"
   28) "86282"
   29) "config-epoch"
   30) "1"
   31) "num-slaves"
   32) "2"
   33) "num-other-sentinels"
   34) "0"
   35) "quorum"
   36) "1"
   37) "failover-timeout"
   38) "60000"
   39) "parallel-syncs"
   40) "1"

在6381端口的redis-server:

172.16.100.7:6381> info replication
# Replication
role:slave
master_host:172.16.100.7
master_port:6380
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:13078
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

启动6379端口的redis-server:

[root@CentOS6 redis]# redis-server /etc/redis/redis.conf
[root@CentOS6 redis]# ss -tnl
State       Recv-Q Send-Q                                                  Local Address:Port                                                    Peer Address:Port
LISTEN      0      128                                                                :::22                                                                :::*
LISTEN      0      128                                                                 *:22                                                                 *:*
LISTEN      0      128                                                                 *:6379                                                               *:*
LISTEN      0      128                                                                 *:26379                                                              *:*
LISTEN      0      128                                                                 *:6380                                                               *:*
LISTEN      0      128                                                                 *:6381                                                               *:*         

在26379端口的redis-sentinel:

172.16.100.7:26379> info
# Server
redis_version:3.2.12
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:b2d74fe5fff7657d
redis_mode:sentinel
os:Linux 2.6.32-504.el6.x86_64 x86_64
arch_bits:64
multiplexing_api:epoll
gcc_version:4.4.7
process_id:31045
run_id:128bbf29c7cea429ef1f3855b616f638904fa57f
tcp_port:26379
uptime_in_seconds:954
uptime_in_days:0
hz:11
lru_clock:4091569
executable:/etc/redis/redis-sentinel
config_file:/etc/redis/redis-sentinel.conf

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

# CPU
used_cpu_sys:2.34
used_cpu_user:0.34
used_cpu_sys_children:0.00
used_cpu_user_children:0.00

# Stats
total_connections_received:1
total_commands_processed:8
instantaneous_ops_per_sec:0
total_net_input_bytes:261
total_net_output_bytes:5418
instantaneous_input_kbps:0.00
instantaneous_output_kbps:0.00
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
evicted_keys:0
keyspace_hits:0
keyspace_misses:0
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:0
migrate_cached_sockets: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=172.16.100.7:6380,slaves=2,sentinels=1
172.16.100.7:26379> SENTINEL slaves mymaster
1)  1) "name"
    2) "172.16.100.7:6379"
    3) "ip"
    4) "172.16.100.7"
    5) "port"
    6) "6379"
    7) "runid"
    8) "78e424a539ad4f36f6dd21c269fef7e6a21d3b74"
    9) "flags"
   10) "slave"
   11) "link-pending-commands"
   12) "0"
   13) "link-refcount"
   14) "1"
   15) "last-ping-sent"
   16) "0"
   17) "last-ok-ping-reply"
   18) "949"
   19) "last-ping-reply"
   20) "949"
   21) "down-after-milliseconds"
   22) "5000"
   23) "info-refresh"
   24) "9338"
   25) "role-reported"
   26) "slave"
   27) "role-reported-time"
   28) "139699"
   29) "master-link-down-time"
   30) "0"
   31) "master-link-status"
   32) "ok"
   33) "master-host"
   34) "172.16.100.7"
   35) "master-port"
   36) "6380"
   37) "slave-priority"
   38) "100"
   39) "slave-repl-offset"
   40) "36081"
2)  1) "name"
    2) "172.16.100.7:6381"
    3) "ip"
    4) "172.16.100.7"
    5) "port"
    6) "6381"
    7) "runid"
    8) "5cd9e09389a83c04046ab7f6c42b21be55586afa"
    9) "flags"
   10) "slave"
   11) "link-pending-commands"
   12) "0"
   13) "link-refcount"
   14) "1"
   15) "last-ping-sent"
   16) "0"
   17) "last-ok-ping-reply"
   18) "949"
   19) "last-ping-reply"
   20) "949"
   21) "down-after-milliseconds"
   22) "5000"
   23) "info-refresh"
   24) "8910"
   25) "role-reported"
   26) "slave"
   27) "role-reported-time"
   28) "530878"
   29) "master-link-down-time"
   30) "0"
   31) "master-link-status"
   32) "ok"
   33) "master-host"
   34) "172.16.100.7"
   35) "master-port"
   36) "6380"
   37) "slave-priority"
   38) "100"
   39) "slave-repl-offset"
   40) "36081"