您的位置:首页 > 数据库 > Redis

Linux之redis服务

2017-02-14 18:44 232 查看


redis简介

redis单纯程模型,支持主从模式,提高可用性,是一个开源项目,经常用来当一个数据结构服务器。其是内存级别的缓存服务器并可实现持久化功能. 据称一百万的变量存储(字串)占用100M内存空间,单台redis服务器可达到5万并发的能力。


redis与memcache的对比


redis的优势

支持丰富的操作
主从复制和集群
就地更新操作
支持持久化(磁盘),避免雪崩效应


memcache优势

多线程,善用多核CPU,更少的阻塞操作
更少的内存开销
更少的内存分配压力
可能有更少的内存碎片


redis的组件


redis-server



redis-cli



redis-benchmark



redis-check-dump & redis-check-aof



redis的工作端口

6379/TCP


redis-cli命令的参数

-h HOST
 :
连接的主机地址或主机名
-p PORT
 :连接的端口
-s socket
 :
指定套接字
-a password
 :
指定连接密码
-r <repeat>
 :
指定命令运行多次


redis-cli中相关的命令


connection相关的命令

auth PASS
 : 认证
ping
 : 测试服务器是否在线
echo "string"
 : 显示string
quit
 : 退出
select #
 : 挑选指定的名称空间(即数据库)
help @connection
 : 获取与连接相关的命令帮助


与服务器端支持的命令

help @server
 : 获取与服务器端相关的命令帮助
bgsave
 : 实现异步将数据集同步到磁盘上
client getname
 : 获取当前客户端的连接名
client kill IP:PORT
 :
指定IP:PORT可关闭相关的连接信息

client list
 : 查看客户端的连接信息
172.16.36.70:6379> client list id=5 addr=172.16.36.70:57606 fd=8 name= age=904 idle=879 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=get


client setname CONNECTION-NAME
:
设定当前连接的名称
info
 : 查看当前服务器的状态信息
info memory
 : 只显示memory段的相关信息
config resetstart
 :
重置info中所统计的数据
config set PARAMETER value
 :
运行时修改设定指定参数的值,只保存在内存中
config rewrite
 : 将修改在内存中的参数值同步到配置文件中
config get dir
 : 查看redis的文件保存目录
dbsize
 : 显示数据库中所有键的数量
lastsave
 : 用来获取最新一次save执行的时间戳
save
 : 保存数据到磁盘
monitor
 : 实时监控所接收到的请求
shutdown
 : 将所有数据从内存同步到磁盘,并安全关闭
shutdown [nosave][save]
 :
关闭程序并选择是否将数据同步到磁盘上
salveof HOST PORT
 :配置主从,当前节点将变成从节点
slowlog
 : 查看慢查询日志,需要开启慢查询日志功能
sync
 : 复制功能的内建命令


与订阅相关的命令

help @pubsub
 : 获取与订阅相关的命令
psubscribe
 : 基于模式进行订阅
publish
 : 向频道发送消息
subscribe CHANNEL
 :
订阅一个频道


redis的认证功能

vim /etc/redis.conf
requirepass zhenping.com

重启redis服务
systemctl restart redis

连接redis并认证的方法
redis-cli -h 172.16.36.70
172.16.36.70:6379> select 0
(error) NOAUTH Authentication required.
172.16.36.70:6379> auth zhenping
OK


redis清空数据库

flushdb
 :
清空当前库

flushall
 : 清空所有库
[root@Centos7 ~]# redis-cli -h 172.16.36.70
172.16.36.70:6379> flushall
OK
172.16.36.70:6379> flushdb
OK



redis的事务功能

通过
multi
,
exec
,
watch
等命令来实现事务功能,将多个命令打包,多个命令按顺序执行,并一次执行完成,并将执行结果一次性全部返回给客户端。redis事务不支持回滚操作,在事务中应避免发生错误(如命令写错等),事务了也将会执行失败。
multi
 :
启动一个事务
exec
 :
执行事务,一次性将事务中的所有操作执行完成后,返回给客户端
watch
 :
乐观锁机制,在EXEC命令执行之前 ,用于监视指定数据键,如果监视的某任意键数据被修改,服务器拒绝执行事务
####建立一个事务
[root@Centos7 ~]# redis-cli -h 172.16.36.70
172.16.36.70:6379> multi
OK
172.16.36.70:6379> set ip 172.16.36.70
QUEUED
172.16.36.70:6379> get ip
QUEUED
172.16.36.70:6379> set prot 8080
QUEUED
172.16.36.70:6379> exec
1) OK
2) "172.16.36.70"
3) OK

####使用watch机制监控键
[root@Centos7 ~]# redis-cli -h 172.16.36.70
172.16.36.70:6379> watch ip
OK
172.16.36.70:6379> multi
OK
172.16.36.70:6379> set ip 172.16.36.71
QUEUED
172.16.36.70:6379> get ip
QUEUED
172.16.36.70:6379> exec
(nil)

说明: 当watch ip指令发出后,其它的请求操作改变了IP键的值,此时新发起的事务中,如果也要改变其值, 此事务申请将会失败


redis的发布和订阅功能(publish/subscribe)

发布和订阅功能被广泛用于构建即时通信应用,比如:网络聊天室和实时广播、实时提醒等。 订阅发布功能就能帮你很轻松地实现通知、监控程序
subsciribe
CHANNEL_NAME
 : 订阅一个频道
publish CHANNEL_NAME
 :
向频道发送一个消息
unsubscribe
CHANNEL_NAME
 : 退订频道
psubscribe
CHANNEL_NAME_PATTERN
 : 基于正则表达式模式定义多个频道
1、订阅一个频道:
72.16.36.70:6379> subscribe news
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "news"
3) (integer) 1

2、向频道发送消息
172.16.36.70:6379> publish news weizhenping
(integer) 1

3、频道会接收下来消息
[root@Centos7 ~]# redis-cli -h 172.16.36.70
172.16.36.70:6379> subscribe news
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "news"
3) (integer) 1
1) "message"
2) "news"
3) "weizhenping"   #此内容为频道发送过来的消息

基于模式的频道订阅示例
1、基于模式订阅频道
[root@Centos7 ~]# redis-cli -h 172.16.36.70
172.16.36.70:6379> PSUBSCRIBE news.i[to]    #订阅了news.io,news,io两个频道
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "news.i[to]"
3) (integer) 1

2、向频道发送消息
172.16.36.70:6379> PUBLISH news.io hello
(integer) 1

3、频道会接收下来消息
[root@Centos7 ~]# redis-cli -h 172.16.36.70
172.16.36.70: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的持久化功能


1、RDB(redisDB)


工作原理

RDB为snapshot(快照)存储机制,其也是redis默认的存储机制,按照事先定制的策略,周期性地将数据从内存中读取出来保存至磁盘,当到达
save
指令指定的时间,redis主进程将fork一个子进程,负责内存中的内容快照并保存到磁盘中。
Linux系统有写时复制机制,父进程与子进程会共享相同的物理页面,当父进程处理写请求时,操作系统为写的数据创建一个副本,因此子进程保存的数据一定是与时间点一致的数据。当子进程将快照写入临时文件后,会使用临时文件替换旧的文件,然后子进程完成退出 。保存的数据文件默认为
dump.rdb
.
如果在SAVE周期之前停电了,会造成部分数据丢失。


数据保存机制

save
 : 在主线程中保存快照,保存时会阻塞所有客户端请求,每次将完整数据写至dump.rdb文件中,会带来大量的IO压力
bgsave
 : 异步保存机制,在后端自动保存,其不会阻塞窝客户端请求


RDB相关的配置参数(/etc/redis/redis.conf)

stop-writes-on-bgsave-error
yes
 : 在基于快照备份时,一旦发生错误,是否停止写操作
rdbcompression yes
 :
rdb文件是否压缩来节约空间
rdbchecksum yes
 : 是否对rdb的镜像文件做校验码检测,当redis启动时会根据事先保存好的校验码进行对比,保证数据的完整性
dbfilename dump.rdb
 :
保存的文件名
dir /var/lib/redis/
 :
文件保存目录
save ""
 : 关闭rdb功能


2、AOF(append only file)


工作原理


redis以顺序IO的方式附加在文件的尾部,将每一次的写命令操作都通过write函数追加到文件后面,其是比RDB更好的持久化方案,但文件会变得越来越大。当redis重启时,可通过执行文件中的命令在内存中重建数据库


数据保存机制

bgrewriteaof
 : 
AOF文件重写
,它不会读取正在使用的AOF文件,而是通过将内存中的数据以命令的方式保存至临时文件中,完成之后替换原来的AOF文件,这样可以减少AOF的大小


AOF重写过程

1、redis主进程通过fork机制创建子线程
2、子进程根据redis内存中现有的数据通过重建命令创建数据库于临时文件中
3、父进程继续接收客户请求,并会把这些请求中的写操作继续追加到原来的AOF文件中,额外地,也将新的写请求放置于一个缓冲队列中
4、子进程重写完成,会通知父进程,父进程把缓冲中的队列命令写到临时文件中
5、父进程用临时文件替换老的AOF文件


AOF相关的配置参数(/etc/redis/redis.conf)

appendonly no
 : 是否启用AOF功能,yes表示启用
appendfilename "appendonly.aof"
 :
aof存储文件
appendfsync always
 :
每次收到写命令,立即写入磁盘
appendfsync everysec
 :
每秒钟写一次,推荐操作
appendfsync no
 : append功能自己触发写操作,将所有操作都提交给OS,由操作系统决定什么时候写
no-appendfsync-no-rewrite no
:
在重写的过程中是否调用fsync
auto-aof-rewrite-percentage
100
 : 在aof文件已经是上次重写时的2倍大小,将自动启动重写操作

auto-aof-rewrite-min-size 64mb
 : 当文件达到64MB才执行重写操作
RDB与AOF同时启用时:
1、bgsave和bgrewriteaof不会同时执行
2、在redis服务器启动用于恢复数据时,会优先使用AOF



redis的主从复制


1、redis的主从复制特点

一个master可以有多个slave
支持链式复制
master以非阻塞方式同步数据至slave,意味着可同时与多个slave同步


2、复制的工作原理

1、主库会自己基于ping check机制来检查从库是否在线
2、如果从库在线就同步数据文件至从服务器端
3、从服务器也可以发送请求同步的请求,主库将启动一个线程,把内存中的数据同步给从库,从库将数据保存至文件中
4、从库再把文件装载到内存中,从而完成复制功能


3、主从相关配置(/etc/redis.conf)

slave-serve-stale-data yes
 :
当主服务器连接不上了,从服务器是否可以使用过期数据响应
repl-diskless-sync no
 :
是否基于diskless机制同步
slave-priority 100
 :
指定从服务器优先级
min-slave-to-write 3
 :
如果从节点小于三个,主服务器将拒绝写操作

min-slave-max-lag 10
 : 从服务器不能晚于主服务器10秒钟,是否将停止复制

如果master使用了requirepass开启了认证功能,从服务器要使用masterauth <password>来连接,使用指定的密码进行认证

主从设置示例:
172.16.36.70 : 主redis服务
172.16.36.71 : 从redis服务

172.16.36.70配置
vim /etc/redis.conf
bind 172.16.36.70

172.16.36.71配置:
vim /etc/redis.conf
bind 172.16.36.71

[root@Centos7 ~]# redis-cli -h 172.16.36.71
172.16.36.71:6379> SLAVEOF 172.16.36.70 6379
OK
172.16.36.71:6379> get ip   #查看是否能获取到主库数据
"172.16.36.70"
172.16.36.71:6379> dbsize
(integer) 3



redis高可用的实现


sentinel机制


工作原理


找一台专用的监控主机,即能提供监控又可以提供配置功能,如果发现master离线了,监控主机会从从节点选择新的主节点。为了不误判,setinel至少奇数个节点,同时监控。如果主节点不在线,多个setinel会协调一个新的主节点,以免发生误判,所有setinel每秒一次向所有服务器发送ping请求,判断节点是否在线。setinel是一个分布式系统,使用流言协议和投票协议来决定故障迁移。可以监控多组redis实例。


sentinel的功用

用于管理多个redis服务,实现HA
监控
通知
自动故障转移


工作过程

启用sentinel时, 首先服务器做自身初始化,运行redis-server中专用于sentinel功能中的代码
初始化sentinel状态,根据给定的配置文件,初始化监控的master服务列表(可以根据master的配置,获取从服务器节点)
创建连向Master的连接


sentinel下线机制

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


setinel程序

redis-sentinel /path/to/sentinel.conf

redis-server /path/to/sentinel
--sentinel



setinel的工作端口

26379/TCP



专用配置文件

/etc/redis-sentinel.conf



redis-sentinel.conf配置参数

prot 26379

dir /tmp


sentinel monitor mymaster 127.0.0.1 6379 2

mymaster: sentinel要监控的实例名称,此名称可以随意取
127.0.0.1 : 主节点的IP地址
6379 : 主节点的端口
2 : sentinel节点的票数,此值要大于sentinel节点数量的半数


sentinel down-after-milliseconds mymaster 30000
 : 判断主节点不在线的默认超时时长,默认30秒

sentinel parallel-syncs mymaster
1
 : 故障转移时最多能有多少个从服务器向主服务器发起同步请求
sentinel failover-timeout mymaster
180000
 : 提升主节点的超时时长,表示提升新的主节点在3分钟内未完成,操作将失败


sentinel专用命令

sentinel masters
 : 列出所有主服务器
sentinel slaves <master name>
 :
获取所有当前redis实例中的从节点信息

sentinel get-master-addr-by name <master name>
 :直接获取当前redis实例主节点的IP地址及端口
172.16.36.74:26379> sentinel get-master-addr-by-name mymaster
1) "172.16.36.72"
2) "6379"


sentinel reset
 : 重置服务器所有状态

sentinel failover <master name>
 :
手动实现故障转移


sentinel配置实例

实验环境说明:
172.16.36.70 : redis主节点
172.16.36.71 : redis从节点
172.16.36.72 : redis从节点
172.16.36.74 : sentinel节点1
172.16.36.75 : sentinel节点2
172.16.36.76 : sentinel节点3

####配置redis主节点
操作主机: 172.16.36.70
#vim /etc/redis.conf
bind 172.16.36.70
daemonize yes
启动服务
#redis-server /etc/redis.conf
[root@Centos7 ~]# ss -tnl
State      Recv-Q Send-Q                                       Local Address:Port                                         Peer Address:Port
LISTEN     0      128                                           172.16.36.70:6379                                                    *:*

####配置redis从节点
操作主机: 172.16.36.71
#vim /etc/redis.conf
bind 172.16.36.71
daemonize yes

启动服务
#redis-server /etc/redis.conf
[root@Centos7 ~]# ss -tnl
State      Recv-Q Send-Q                                       Local Address:Port                                         Peer Address:Port
LISTEN     0      128                                           172.16.36.70:6379                                                    *:*

配置主节点信息
[root@Centos7 ~]# redis-cli -h 172.16.36.71 -p 6379
172.16.36.71:6379> SLAVEOF 172.16.36.70 6379
OK

操作主机: 172.16.36.72
#vim /etc/redis.conf
bind 172.16.36.72
daemonize yes

启动服务
#redis-server /etc/redis.conf
[root@Centos7 ~]# ss -tnl
State      Recv-Q Send-Q                                       Local Address:Port                                         Peer Address:Port
LISTEN     0      128                                           172.16.36.70:6379                                                    *:*

配置主节点信息
[root@Centos7 ~]# redis-cli -h 172.16.36.71 -p 6379
172.16.36.71:6379> SLAVEOF 172.16.36.70 6379
OK

####配置sentinel节点
操作主机: 172.16.36.74
# vim /etc/redis-sentinel.conf
port 26379
dir "/tmp"
daemonize yes
sentinel monitor mymaster 172.16.36.70 6379 2
sentinel parallel-syncs mymaster 3
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 180000

启动服务
redis-sentinel /etc/redis-sentinel.conf

查看服务启动状态
users:(("master",2112,14))
[root@Centos7 ~]# ss -tln
State      Recv-Q Send-Q                                       Local Address:Port                                         Peer Address:Port
LISTEN     0      128                                                      *:26379                                                   *:*

操作主机: 172.16.36.75
# vim /etc/redis-sentinel.conf
port 26379
dir "/tmp"
daemonize yes
sentinel monitor mymaster 172.16.36.70 6379 2
sentinel parallel-syncs mymaster 3
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 180000

启动服务
redis-sentinel /etc/redis-sentinel.conf

查看服务启动状态
users:(("master",2112,14))
[root@Centos7 ~]# ss -tln
State      Recv-Q Send-Q                                       Local Address:Port                                         Peer Address:Port
LISTEN     0      128                                                      *:26379                                                   *:*

操作主机: 172.16.36.76
# vim /etc/redis-sentinel.conf
port 26379
dir "/tmp"
daemonize yes
sentinel monitor mymaster 172.16.36.70 6379 2
sentinel parallel-syncs mymaster 3
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 180000

启动服务
redis-sentinel /etc/redis-sentinel.conf

查看服务启动状态
users:(("master",2112,14))
[root@Centos7 ~]# ss -tln
State      Recv-Q Send-Q                                       Local Address:Port                                         Peer Address:Port
LISTEN     0      128                                                      *:26379                                                   *:*

查看sentinel相关的日志信息
tailf /var/log/redis/redis-sentinel.log
[32524] 25 Mar 10:05:02.290 # Sentinel runid is a44025e518b65c512340c48535df119496f7a0d8
[32524] 25 Mar 10:05:02.291 # +monitor master mymaster 172.16.36.70 6379 quorum 2
[32524] 25 Mar 10:05:32.322 # +sdown slave 172.16.36.71:6379 172.16.36.71 6379 @ mymaster 172.16.36.70 6379
[32524] 25 Mar 10:05:46.311 * +sentinel sentinel 172.16.36.76:26379 172.16.36.76 26379 @ mymaster 172.16.36.70 6379
[32524] 25 Mar 10:05:57.071 * +sentinel sentinel 172.16.36.75:26379 172.16.36.75 26379 @ mymaster 172.16.36.70 6379
[32524] 25 Mar 10:09:03.727 # +sdown master mymaster 172.16.36.70 6379

将当前的Master节点shudown,查看sentinel的相关日志信息
[32524] 25 Mar 10:09:03.747 # +new-epoch 4
[32524] 25 Mar 10:09:03.749 # +vote-for-leader 90c011868befc3047a8527886efce8f8c6f9ea34 4
[32524] 25 Mar 10:09:03.836 # +odown master mymaster 172.16.36.70 6379 #quorum 3/2
[32524] 25 Mar 10:09:03.836 # Next failover delay: I will not start a failover before Fri Mar 25 10:15:04 2016
[32524] 25 Mar 10:09:04.854 # +config-update-from sentinel 172.16.36.75:26379 172.16.36.75 26379 @ mymaster 172.16.36.70 6379
[32524] 25 Mar 10:09:04.854 # +switch-master mymaster 172.16.36.70 6379 172.16.36.72 6379
[32524] 25 Mar 10:09:04.855 * +slave slave 172.16.36.71:6379 172.16.36.71 6379 @ mymaster 172.16.36.72 6379
[32524] 25 Mar 10:09:04.856 * +slave slave 172.16.36.70:6379 172.16.36.70 6379 @ mymaster 172.16.36.72 6379

对当前主节点监控sentinel的活跃探测信息
root@Centos7 ~]# redis-cli -h 172.16.36.72
172.16.36.72:6379> monitor
OK
1458878723.052705 [0 172.16.36.76:53255] "PING"
1458878723.402835 [0 172.16.36.75:38413] "PING"
1458878723.586806 [0 172.16.36.74:32824] "PING"
1458878723.859748 [0 172.16.36.75:38413] "PUBLISH" "__sentinel__:hello" "172.16.36.75,26379,90c011868befc3047a8527886efce8f8c6f9ea34,4,mymaster,172.16.36.72,6379,4"
1458878724.099837 [0 172.16.36.76:53255] "PING"
1458878724.152776 [0 172.16.36.76:53255] "PUBLISH" "__sentinel__:hello" "172.16.36.76,26379,21a0a795010287138b6efc636d03edcce66bcd56,4,mymaster,172.16.36.72,6379,4"
1458878724.454214 [0 172.16.36.75:38413] "PING"
1458878724.617819 [0 172.16.36.74:32824] "PING"
1458878724.693888 [0 172.16.36.74:32824] "PUBLISH" "__sentinel__:hello" "172.16.36.74,26379,a44025e518b65c512340c48535df119496f7a0d8,4,mymaster,172.16.36.72,6379,4"

使用info sentinel命令查看主从信息
172.16.36.74:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=mymaster,status=ok,address=172.16.36.72:6379,slaves=2,sentinels=3


Redis Clustering

在redis3.0版本中引入clustering功能, 是去中心化的分布式数据库,通过分片机制进行数据分布,clustering内的每个节点仅有数据库一部分数据,每个节点都有全局元数据,通过查找元数据,即可查询到数据存放在哪台服务器


分布式解决方案


Twemproxy(Twitter)

代理分片机制
优点
非常稳定,企业方案

缺点
单点故障
需要依赖第三方软件,如Keeplived
无法平滑地横向扩展
没有后台界面
代理分片机制引入更多的来回次数并提高延迟
单核模式,无法充分利用多核,除非多实例
Twitter官方肉串不再继续使用


Codis(豌豆荚)

代理分片机制
2014年11月开源
基于GO以及C语言开发
优点
非常稳定,企业级方案
数据自动平衡
高性能
简单的测试显示较Twemproxy快一倍
善用多核CPU
简单
没有paxos类的协调机制
没有主从复制

有后台界面

缺点
代理分片机制引入更多的来回次数并提高延迟
需要第三方软件支持协调机制
目前支持zookeeper及Etcd

不支持主从复制 ,需要另外实现
Codis采用proxy方案,所有必然会带来单机性能的损失
经测试,在不开Pipeline的情况下,大概会损失40%左右的性能


Redis Cluster(官方)

官方实现
需要3.0或更高版本
优点
无中心的P2P Gossip分散式模式
更少的来回次数并降低延迟
自动于多个redis节点进行分片
不需要第三方软件支持协调机制

缺点
依赖于redis 3.0或更高版本
需要时间验证其稳定性
没有后台界面
需要智能客户端
redis客户端必须支持redis cluster架构
较Codis有更多的维护升级版本

此文章来自于【http://www.jianshu.com/p/43991e4673ee】
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Redis