[toc]
redis 常用功能
KV cache and store
REmote DIctionary Server(远程字典服务器)
redis 运行都在内存中来实现,周期性的写入磁盘,来实现持久功能;
基本知识
KV cache and store
in-memory;
持久化 ;
主从(借助于sentinal实现一定意义上的HA);
Clustering(分布式);
数据结构服务器:
String, List, Hash, Set, Sorted Set, Bitmap,HperLoglogs;
Memcached 与 Redis的区别:
1、Memcached 是一个分布式的内存对象缓存系统;
2、Reis 可以实现持久存储的;
3、Mecached 是一个LUR 缓存,将过期数据清理出去;
4、Redis支持更多的数据类型;
5、Memcached 是多线程;
6、Redis是单线程;
7、二者的性能不相上下;
Redis 3.0的LRU算法的改进:
预设随机取5个样本,插入并排序至一个pool, 移除最佳者,如此反复;
走到内存用理小于maxmemory的设定;
样本5比先前的3多;
从局部最优趋向全局最优;
存储系统三类:
RDBMS
NoSQL:
KV NoSQL: redis
Column Family NoSQL: HBase
Documentation NoSQL: MongoDB
Graph NoSQL: Neo4j
NewSQL(支持分布式)
Redis的组件:
redis.io(官方站点)
Commands
redis-server
redis-cli
Command line interface
redis-benchmark
Benchmarking utility
redis-check-dump & redis-check-aof
Corrupted RDB/AOF files utilities
Redis守护进程
# vim /etc/redis.conf
监听6379端口;
tcp-backlog 511 #是redis守护进程的等队列,当并发较高时,再找位置来缓存新请求;
bind # 是指监听的地址;
bind 127.0.0.1 172.16.55.128
unixsocket /tmp/redis.sock # 当服务和redis在一台服务器上使用socket来通信,提高效率;
unixsocketperm 700
timeout #当一个客端连接多久后,认为超时,0表示禁用,认为一直存在;
tcp-keepaoive 0
loglevel notice
logfile /var/log/redis/redis.log
databases 16 # 表示可以使用多少个数据库;
save <sencods> <changes> # 如果多少秒发生多少变化则存储,因此这取决于业务模型;
save "" #这样写表示禁用redis持久化功能;
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
dbcheksum yes
dbfilename dump.rdb
dir /var/lib/redis
# 配置以为成为从服务器
salveof ip # 这里指定主服务器的ip即可;
maxclients 100000
appendonly yes # 开启appendonly 持久化功能;
appendfsync everysec # 是否使用fsync来持久化;
# redis服务端的参数,大多可以在redis-cli连接到服务器后进行动态修复或修改的;
redis-cli 常用命令
# redis-cli -p 25612
127.0.0.1:25612> AUTH xxxxxxx
127.0.0.1:25612> HELP APPEND # help 用来查看帮助
127.0.0.1:25612> CLIENT LIST
id=3 addr=127.0.0.1:25666 fd=5 name= age=275 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
127.0.0.1:25612> SELECT 1 # 第开第几个数据库,也可以理解成为名称空间;
127.0.0.1:25612> SELECT 1
OK
127.0.0.1:25612[1]> SET disto fedora
OK
127.0.0.1:25612[1]> GET disto
"fedora"
127.0.0.1:25612[1]> SET disto centos
OK
127.0.0.1:25612[1]> STRLEN disto
(integer) 6
127.0.0.1:25612[1]> DECR count
(integer) -1
127.0.0.1:25612[1]> DECR count
(integer) -2
127.0.0.1:25612[1]> DECR count
(integer) -3
127.0.0.1:25612[1]> SET disto gentoo NX # 显示为未能执行的操作,该值不存在则设定;
(nil)
127.0.0.1:25612[1]> SET foo bar XX # 该值则在则设定;
(nil)
127.0.0.1:25612[1]> SADD w1 mon tue wed thu sat sun
(integer) 6
127.0.0.1:25612[1]> SADD w1 mon tue wed thu fre sat sun
(integer) 1
127.0.0.1:25612[1]>
127.0.0.1:25612[1]> SADD w2 tue thu day
127.0.0.1:25612[1]> ZADD weekday1 1 mon 2 tue 3 wed
(integer) 3
127.0.0.1:25612[1]> ZCARD weekday1
(integer) 3
127.0.0.1:25612[1]> ZRANK weekday1 tue
(integer) 1
127.0.0.1:25612[1]> ZRANK weekday1 mon
(integer) 0
(integer) 3
127.0.0.1:25612[1]> SINTER w1 w2 # 求两个集合的交集;
1) "thu"
2) "tue"
127.0.0.1:25612[1]> SUNION w1 w2 # 求两个集合的并集;
1) "sun"
2) "wed"
3) "sat"
4) "day"
5) "tue"
6) "thu"
7) "mon"
8) "fre"
127.0.0.1:25612[1]> SPOP w1 # 弹出一个元素 ;
"tue"
127.0.0.1:25612[1]> SPOP w1
"sun"
127.0.0.1:25612[1]> SISMEMBER w1 day # 表示已经没有这个元素;
(integer) 0
127.0.0.1:25612[1]> SISMEMBER w1 sat
(integer) 1
127.0.0.1:25612[1]> ZRANGE weekday1 0 1
1) "mon"
2) "tue"
127.0.0.1:25612[1]> HSET h1 a mon
(integer) 0
127.0.0.1:25612[1]> HGET h1 a
"mon"
127.0.0.1:25612[1]> HSET h1 b tue
(integer) 1
127.0.0.1:25612[1]> HGET h1 a
"mon"
127.0.0.1:25612[1]> HGET h1 b
"tue"
127.0.0.1:25612[1]> HVALS h1
1) "mon"
2) "tue"
127.0.0.1:25612[1]> HKEYS h1
1) "a"
2) "b"
Strings: 字串
SET key value [EX #] [NX|XX]
GET
INCR
DECR
EXIST
Lists: 列表
LPUSH
RPUSH
LDROP
RPOP
LINDEX
LSET
Sets: 集合
SADD
SINTER
SUNTON
SPOP
SISMEMBER
Sorted Sets 有序集合, 其命令都以Z开头
ZADD
ZRANGE
ZCARD
ZRANK
Hashes: 一组关联数的集合
HSET
HSETNX
HGET
HKEYS
HVALS
HDEL
认证实现方法
(1) redis.conf
requirepass PASSWORD
(2) redis-cli
AUTH PASSWD
清空数据库
# FLUSHDB: 清空当前库
# FLUSHALL: 清空所有库
事务
# 通过MULTI, EXEC, WATCH等命令实现事务功能;
# 将一个或多个命令归并为一个操作提请服务器按顺序执行的机制;
# Redis数据不支持回滚操作;
# MULTI: 启动一个事务,中间的所有命令会放置在队列中;
# EXEC: 执行事务;
# 一次性将事务中的所有操作执行完成后返回给客户端;
127.0.0.1:25612> MULTI
OK
127.0.0.1:25612> SET ip 172.16.55.123
QUEUED
127.0.0.1:25612> GET ip
QUEUED
127.0.0.1:25612> SET port 8080
QUEUED
127.0.0.1:25612> GET port
QUEUED
127.0.0.1:25612> EXEC
1) OK
2) "172.16.55.123"
3) OK
4) "8080"
# WATCH: 乐观锁, 在EXEC命令执行之间有用于监视指定数量键;
#如果监视中的某任意键数据被修改,则服务器拒绝执行事务;
# 打开两个终端
term1
127.0.0.1:25612> WATCH ip
OK
127.0.0.1:25612> MULTI
OK
127.0.0.1:25612> SET ip 10.0.0.1
QUEUED
127.0.0.1:25612> GET ip
QUEUED
term2
127.0.0.1:25612> GET ip
"172.16.55.123"
127.0.0.1:25612> SET ip 172.16.55.123
OK
127.0.0.1:25612> GET ip
"172.16.55.123"
term1
127.0.0.1:25612> EXEC
(nil)
# 监控的一个键,EXEC之前键发生了改动,EXEC将拒绝提交;
Connection相关的命令:
AUTH
127.0.0.1:25612> HELP PING
PING [message]
summary: Ping the server
since: 1.0.0
group: connection
127.0.0.1:25612> PING
PONG
127.0.0.1:25612> ECHO "hello redis"
"hello redis"
127.0.0.1:25612>
QUIT
127.0.0.1:25612> HELP @connection
Server相关的命令
CLIENT GETNAME
CLIENT KILL ip:port
127.0.0.1:25612> CLIENT SETNAME localconn
OK
127.0.0.1:25612> CLIENT GETNAME
"localconn"
127.0.0.1:25612> HELP INFO # 获取当前服务器的状态及信息;
INFO [section]
summary: Get information and statistics about the server
since: 1.0.0
group: server
127.0.0.1:25612> INFO CPU
# CPU
used_cpu_sys:474.20
used_cpu_user:258.88
used_cpu_sys_children:0.01
used_cpu_user_children:0.00
CONFIG RESETSTAT
CONFIG SET PARAMETER value
CONFIG REWRITE
DBSIZE
# 跟持久化相关的数据
BGSAVE
SAVE
LASTSAVE
monitor # 实时监控对数据的请求
SHUTDOWN SAVE #将数据安全的同步到磁盘后关闭redis-server
redis 发布与订阅功能(publish/subscribe)
# 频道: 消息队列
# SUBSCRIBE: 订阅一个或多个队列;
# PUBLISH: 向频道发布消息;
# UNSUBSCRIBE: 退订此前订阅的频道;
# PSUBSCRIBE: 模式订阅;
# term1 中开始一个频道;
127.0.0.1:25612> SUBSCRIBE news
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "news"
3) (integer) 1
# term2 中向一个频道中发布消息;
127.0.0.1:25612> PUBLISH news "hello renjin"
(integer) 1
# term1 中可以收到消息;
1) "message"
2) "news"
3) "hello renjin"
# term1 中使用扩展模式开启两个频道;
127.0.0.1:25612> PSUBSCRIBE "rj.i[to]"
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "rj.i[to]"
3) (integer) 1
# term2 中向两个频道发布消息;
127.0.0.1:25612> PUBLISH rj.io "hello RenJin"
(integer) 1
127.0.0.1:25612> PUBLISH rj.it "hello SSJinYao"
(integer) 1
# term1 中可以收到两条消息;
1) "pmessage"
2) "rj.i[to]"
3) "rj.io"
4) "hello RenJin"
1) "pmessage"
2) "rj.i[to]"
3) "rj.it"
4) "hello SSJinYao"
Redis 的持久化:
# 提供了RDB和AOF两种机制;
RDB: snapshot: 二进制格式; 按事先定制的策略,周期性地将数据保存至磁盘:数据文件默认为dump.rdb;
客户端 也可以使用SAVE或BGSAVE命令启快照保存机制;
SAVE:同步,在主线程中保存快照; 此时会阻塞所有客户端请求;
BGSAVE: 异步,
AOF:Aappend Only Fil
记录每一次写操作至指定 的文件尾部实现持久化; 当redis重启时,可通过重新执行文件中的命令在内存重建数据库;
BGREWRITEAOF: AOF文件重写:
不会读取正在使用的AOF文件,而通过将内存中的数据以命令的方式保存到临时文件中,完之后替换原来的AOF文件;
RDB:默认保存策略,取决于磁盘IO能力,与客户端对redis的读写;
SAVE 900 1
SAVE 300 10
SAVE 60 1000
stop-writes-on-bgsave-error yes # 在进行快照备份时,监控到持久化发现错误时,是否停止下来; 会报告一个访问错误;
rdbcompression yes # 是否采用压缩来节省使有空间,当然消耗cpu使用周期;
rdbchecksum yes # 是否对rdb做校验码操作;
dbfilename dump.rdb # 指明文件名;
dir /var/lib/redis #指明保存文件的位置;
127.0.0.1:25612> CONFIG GET dir
1) "dir"
2) "/var/lib/redis"
AOF:
重写过程:
(1) redis 主进程通过fork创建子进程;
(2) 子进程根据redis内存中的数据创建数据库重建命令序列于临时文件中;
(3) 父进程继承client的请求时,并会把这些请求中的写操作继续追加至原来的AOF文件;
额外地,这些新的写请求还会被放置于一个缓冲队列中;
(4) 子进程重写完成,会通知父进程,父进程把缓冲中的命令写到临时文件中;
(5) 父进程用临时文件替换老的aof文件;
appenonly no #没有开启AOF 功能;
appendfilename "appendonly.aof" # 文件名
appendfsync eversec # 每秒中写一次
no-appedfsync-no-rewrite no # 对新的操作不做fsync,而是放在缓存队列中的;
auto-aof-rewrite-percentage 100 # 当前afo 文件是上次的两倍时,再重新触发重写操作;
auto-aof-rewrite-min-size 64mb #
127.0.0.1:25612> CONFIG SET appendonly yes
OK
# 注意: 持久本身不能取代备份: 还应该制定备份策略,对redis数据库进行定期备份;
# RDB与AOF同时启用:
(1) BGSAVE和BGREWRITEAOF 不会同是执行;
(2) 在Redis服务器启用于恢复数据时,会优先使用AOF;
Redis复制:
特点:
一个Master 可以有多个Slave;
支持链式复制;
Master以非阻塞方式同步数据至slave; 注:主服务器不建议关闭持久化;
slave:
> SLAVEOF MASTER_IP MASTER_PORT
min-salves-to-write 3 # 至少应该有三个从节点,小于三个,禁止主服务器写操作;
min-salves-max-lag # 从服务器必需不能滞后于服务器10秒以上;
注意: 如果master使用requirespass开启了认证功能,从服务器要使用masterauth <PASSWORD>;
来连入服务请求使用此密码进行认证;
sentinal: 万一主服务器岩了,那么它会从从服务器节点中选则一台服务器成为主节点;
万sentinal 故障,或者连接不上主节点时,需要sentinal配置多个节点;
sentinel:
用于管理多个redis服务实现HA;
监控;
通知;
自动故障转移;
本质上,sentinel也是redis的分布式功能;
使用流言协议、投票协议;
程序:
redis-sentinel /path/to/file.conf
redis-server /path/to/file.conf
(1) 服务器自身初始化,运行redis-server中专用于sentinel功能的代码;
(2) 初始化sentinel状态,根据给定的配置文件,初始化监控的master服务器列表;
(3) 创建连向master的连接;
专用配置文件: /etc/redis-sentinel.conf
(1) # sentinel monitor <master-name> <ip> <redis-port> <quorum>
sentinel monitor mymaster 127.0.0.1 6379 2
(2) # sentinel down-after-millisenconds <master-name> <millisends>
sentinel down-afer-millisenconds mymaster 3000
(3) # sentinel parellel-syncs <master-name> <numslaves>
seninel parallel-syncs mymaster 1
(4) # sentinel failover-timeout <master-name> <milliseconds>
sentinel failover-timeout mymaster 180000
主观下线,客观下线:
主观下线: 一个sentinel实例判断出某节点下线:
客观下线:多个seninel 节点协商后判断出某节点下线:
专用命令:
SENTINEL masters
SENTINEL slaves <master name>
SENTINEL get-master-addr-by-name <master name>
SENTINEL reset
SENTINEL failover <master name>
Clustering:
分布式数据库,通过分片机制进行数据分布,clustering内的每个子节点仅数据库的一部分数据;