Redis 缓存技术(运维篇)

企业缓存产品介绍

Memcached:

优点:高性能读写、单一数据类型、支持客户端式分布式集群、一致性hash。多核结构、多线程读写性能高。

缺点:无持久化、节点故障可能出现缓存穿透、分布式需要客户端实现、跨机房数据同步困难、架构扩容复杂度高

Redis:

优点:高性能读写、多数据类型支持、数据持久化、高可用架构、支持自定义虚拟内存、支持分布式分片集群、单线程读写性能极高。

缺点:多线程读写较Memcached慢。

Tair:

优点:高性能读写、支持三种存储引擎(ddb、rdb、ldb)、支持高可用、支持分布式分片集群、支撑了几乎所有淘宝业务的缓存。

缺点:单机情况下,读写性能较其他两种产品较慢。

使用场景介绍:

  • Memcached:多核的缓存服务,更加适合于多用户并发访问次数较少的应用场景
  • Redis:单核的缓存服务,单节点情况下,更加适合于少量用户,多次访问的应用场景。

Redis 功能介绍

  • 数据类型丰富
  • 支持持久化
  • 多种内存分配及回收策略
  • 支持弱事务
  • 消息队列、消息订阅
  • 支持高可用
  • *支持分布式分片集群
  • 缓存穿透\雪崩
  • Redis API

Redis 单机安装(3.2.12 版本)

软件下载

# 下载软件包
wget http://download.redis.io/releases/redis-3.2.12.tar.gz

# 解压
tar xzf redis-3.2.12.tar.gz -C /application

# 设置软连接
ln -s /application/redis-3.2.12/ /application/redis

安装

# 安装依赖
yum -y install gcc automake autoconf libtool make

# 编译
cd /application/redis
make

环境变量

# 添加环境变量
echo 'export PATH=/application/redis/src:$PATH' >>/etc/profile

# 生效环境变量
source /etc/profile 

启动Redis

redis-server & 

连接测试

# 进入redis交互
redis-cli 

127.0.0.1:6379> set num 10
OK
127.0.0.1:6379> get num 
"10"

Redis 基本管理

基础配置文件介绍

# 创建目录
mkdir -p /data/redis/6379

# 创建redis配置文件
[root@redis ~]# vim /data/redis/6379/redis.conf
#是否后台运行
daemonize yes	
#端口号
port 6379			
#redis 日志文件
logfile /data/redis/6379/redis.log	
#持久化文件存储位置
dir /data/redis/6379
#RDB持久化数据文件
dbfilename dump.rdb

重启/检查

# 关闭
redis-cli shutdown 

# 启动,指定redis.conf
redis-server /data/6379/redis.conf 

# 查看端口是否启动
netstat -lntup|grep 6379

Redis 安全配置

Redis默认开启了保护模式,只允许本地回环地址登录并访问数据库。

解决方法

  • Bind :指定IP进行监听
  • 增加requirepass

配置方法

[root@db01 redis]# vim /data/redis/6379/redis.conf 
# 监听地址(允许连接Redis的地址)
bind 127.0.0.1 10.4.7.51
# 连接Redis的密码
requirepass 123456

验证

# 方法一: 命令行指定密码( -a )
[root@db01 redis]# redis-cli -a 123456 -h 10.4.7.51
10.4.7.51:6379> set name Zoro
OK
10.4.7.51:6379> get name
"Zoro"

# 方法二: 内部验证( AUTH )
[root@db01 redis]# redis-cli 
127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> get name
"Zoro"

# 指定端口
[root@db01 redis]# redis-cli -a 123456 -h 10.4.7.51 -p 6379

Redis 持久化配置

内存数据保存到磁盘。可以有效防止,在redis 宕机后,缓存失效的问题。

持久化分类

  • RDB 持久化

    特点:可以在指定的时间间隔内生成数据集的时间点快照。

    优点:速度快,适合于用作备份,主从复制也是基于RDB持久化功能实现的。

    缺点:可能会有数据丢失。

  • AOF 持久化

    特点:记录服务器执行的所有变更操作,并在服务器启动时,通过重新执行这些命令来还原数据集。
    AOF 文件中的命令全部以 Redis 协议的格式来保存,新命令会被追加到文件的末尾。

    优点:可以最大程度保证数据不丢。

    缺点:日志记录量级比较大。

RDB 持久化配置

[root@db01 ~]# vim  /data/redis/6379/redis.conf 
#RBD持久化文件目录 
dir /data/redis/6379
#RBD持久化文件
dbfilename dump.rdb
#RBD自动持久化功能配置
save 900 1
save 300 10
save 60 10000

#################
配置分别表示:
900秒	内有1个更改,执行save
300秒	内有10个更改,执行save
60秒		内有10000个更改,执行save

AOF 持久化配置

[root@db01 ~]# vim  /data/redis/6379/redis.conf 
#是否打开aof日志功能
appendonly yes
#刷写策略
appendfsync everysec 



## 刷写策略:
appendfsync always	   -- 每一个命令,都立即同步到aof
appendfsync everysec   -- 每秒写1次
appendfsync no		  -- 写入工作交给操作系统,由操作系统判断缓冲区大小,统一写入到aof

Redis 持久化方式与区别

  • RDB:基于快照的持久化,速度更快,一般用作备份,主从复制也是依赖于rdb持久化功能
  • AOF:以追加的方式记录redis操作日志的文件。可以最大程度的保证redis数据安全,类似于mysql的binlog

Redis 数据类型

String 字符串类型

string 是 redis 最基本的类型,一个 key 对应一个 value。

string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。

string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。

String 应用场景:session 共享,常规计数(微博数,粉丝数,订阅、礼物等)

Hash 哈希类型

Redis中的散列可以看成具有String key和String value的map容器,可以将多个key-value存储到一个key中。每一个Hash可以存储4294967295个键值对。

Hash 应用场景:存储一些结构化的数据,比如用户的昵称、年龄、性别、积分等,存储一个用户信息对象数据。

List 列表类型

Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部或者尾部.

List中可以包含的最大元素数量是4294967295。

List应用场景:经常会被用于消息队列的服务,以完成多程序之间的消息交换。

Set 集合类型(join union)

edis的Set是string类型的无序集合。和列表一样,在执行插入和删除和判断是否存在某元素时,效率是很高的。集合最大的优势在于可以进行交集并集差集操作。Set可包含的最大元素数量是4294967295。

应用场景:1.利用交集求共同好友。2.利用唯一性,可以统计访问网站的所有独立IP。3.好友推荐等

SortedSet(有序集合)

和set很像,都是字符串的集合,都不允许重复的成员出现在一个set中。他们之间差别在于有序集合中每一个成员都会有一个分数(score)与之关联,Redis正是通过分数来为集合中的成员进行自动排序。尽管有序集合中的成员必须是唯一的,但是分数(score)却可以重复。

应用场景:排行榜应用,取TOP N操作等

Redis 发布订阅

PUBLISH channel msg
    将信息 message 发送到指定的频道 channel

SUBSCRIBE channel [channel ...]
    订阅频道,可以同时订阅多个频道

UNSUBSCRIBE [channel ...]
    取消订阅指定的频道, 如果不指定频道,则会取消订阅所有频道

PSUBSCRIBE pattern [pattern ...]
    订阅一个或多个符合给定模式的频道,每个模式以 * 作为匹配符,比如 it* 匹配所   有以 it 开头的频道( it.news 、 it.blog 、 it.tweets 等等), news.* 匹配所有 以 news. 开头的频道( news.it 、 news.global.today 等等),诸如此类

PUNSUBSCRIBE [pattern [pattern ...]]
    退订指定的规则, 如果没有参数则会退订所有规则

PUBSUB subcommand [argument [argument ...]]
    查看订阅与发布系统状态
        
注意:使用发布订阅模式实现的消息队列,当有客户端订阅channel后只能收到后续发布到该频道的消息,之前发送的不会缓存,必须Provider和Consumer同时在线。

举例说明

-- 发布订阅例子
# 窗口1:订阅频道 zzgw
127.0.0.1:6379> SUBSCRIBE zzgw 

#窗口2: 在zzgw频道发布消息
127.0.0.1:6379> PUBLISH zzgw 'www.onelpc.com'

#窗口1: 订阅者的客户端输出
1) "message"
2) "zzgw"
3) "www.onelpc.com"

-- 订阅多频道:
# 窗口1:订阅频道:aa  zz*(zz开头的)
127.0.0.1:6379> PSUBSCRIBE aa  zz*
#窗口2:发表消息
127.0.0.1:6379> PUBLISH aa 'this is aaa'
127.0.0.1:6379> PUBLISH zz 'this is zzz'
127.0.0.1:6379> PUBLISH zz1 'this is zzz1'
#订阅者的客户端输出
1) "pmessage"
2) "aa"
3) "aa"
1) "pmessage"
2) "zz*"
3) "zz"
4) "this is zzz"
1) "pmessage"
2) "zz*"
3) "zz1"
4) "this is zzz1"

Redis 弱事务

Redis的事务是基于队列实现的。redis 是乐观锁机制

MULTI	-- 用于标记事务块的开始。
EXEC	-- 在一个事务中执行所有先前放入队列的命令,然后恢复正常的连接状态。
DISCARD	-- 清除所有先前在一个事务中放入队列的命令,然后恢复正常的连接状态。
WATCH	-- 当某个事务需要按条件执行时,就要使用这个命令将给定的键设置为受监控的。
UNWATCH	-- 清除所有先前为一个事务监控的键。

举个栗子

127.0.0.1:6379> MULTI 
OK
127.0.0.1:6379> set a 1 
QUEUED
127.0.0.1:6379> DISCARD		#DISCARD,事务被清除
OK
127.0.0.1:6379> get a 		
(nil)
127.0.0.1:6379> MULTI 
OK
127.0.0.1:6379> set a 1
QUEUED
127.0.0.1:6379> EXEC 		#EXEC,事务被执行
1) OK
127.0.0.1:6379> get a
"1"

Redis 服务器管理命令

info	# 工作情况(内存使用状态)
	-- info memory		#内存情况(used_memory_rss_human)
	-- INFO Replication	#主从状态

config get *		# 查看Redis状态
config set *		# 修改redis信息
Dbsize				# key的个数
FLUSHALL 			# 清空所有数据(生产禁用) 
Client list			# 连接列表
Client kill ip:port	# 杀死连接
CONFIG RESETSTAT 	# 重置统计
CONFIG GET/SET 		# 动态修改
select 				# 切换库,redis支持16个库(0-16),默认是0
FLUSHDB 			# 清空当前库
MONITOR 			# 监控实时指令(redis-cli -a 123456 monitor >/tmp/redis.txt)
SHUTDOWN 			# 关闭Redis服务器

Redis 主从(Master-Replicaset)

Master-Replicaset 架构

Master-Replicaset 原理

1)副本库通过 slaveof 命令,连接主库,在发送SYNC给主库

2)主库收到SYNC,会立即触发BGSAVE,后台保存RDB,发送给副本库

3)副本库接收后会应用RDB快照

4)主库会陆续将中间产生的行的操作,保存并发送给副本库

5)到此,主复制集就正常工作了

6)再次之后,主库只要发生新的操作,都会以命令传播的形式自动发送给副本库

7)所有复制相关信息,从info信息中都可以查到,即使重启任何节点,他的主从关系依然存在

8)如果发生主从关系断开时,从库数据没有任何损坏,在下次重连之后,从库发送PSYNC给主库

9)主库只会将从库确实部分的数据同步给从库应用,达到快速恢复主从的目的

主从数据一致性保证

min-slaves-to-write 1	## 最小从服务器数
min-slaves-max-lag 3	## 指定网络延迟的最大值

##如果条件不满足,主服务器会拒绝写操作并返回一个错误。

Master-Replicaset 实现

环境准备

mkdir -p /data/638{0..2}

配置文件示例

# 6380实例
cat >/data/6380/redis.conf <<EOF
port 6380
daemonize yes
pidfile /data/6380/redis.pid
loglevel notice
logfile /data/6380/redis.log
dbfilename dump.rdb
dir /data/6380
requirepass 123
masterauth 123
EOF

# 6381实例
cat >/data/6381/redis.conf<<EOF
port 6381
daemonize yes
pidfile /data/6381/redis.pid
loglevel notice
logfile /data/6381/redis.log
dbfilename dump.rdb
dir /data/6381
requirepass 123
masterauth 123
EOF

# 6382实例
cat >/data/6382/redis.conf<<EOF
port 6382
daemonize yes
pidfile /data/6382/redis.pid
loglevel notice
logfile /data/6382/redis.log
dbfilename dump.rdb
dir /data/6382
requirepass 123
masterauth 123
EOF

启动集群

redis-server /data/6380/redis.conf
redis-server /data/6381/redis.conf
redis-server /data/6382/redis.conf

开启主从复制

# 从库操作(6381,6382)
redis-cli -p 6381 -a 123 SLAVEOF 127.0.0.1 6380
redis-cli -p 6382 -a 123 SLAVEOF 127.0.0.1 6380

查询主从状态

redis-cli -p 6381 -a 123 info replication	#从库
redis-cli -p 6382 -a 123 info replication	#从库

# 主库查看
redis-cli -p 6380 -a 123 info replication	#主库
---------------------------------------------------------
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6381,state=online,offset=127,lag=0
slave1:ip=127.0.0.1,port=6382,state=online,offset=127,lag=0
master_repl_offset:127

Master-Replicaset 问题

一旦主节点宕机,从节点上位,需要人为修改所有应用方的主节点地址(改为新的master地址),还需要命令所有从节点复制新的主节点。

Redis-sentinel(哨兵)

Redis-Sentinel是Redis官方推荐的高可用性解决方案,当用redis作master-slave的高可用时,如果master本身宕机,redis本身或者客户端都没有实现主从切换的功能。
而redis-sentinel就是一个独立运行的进程,用于监控多个master-slave集群,自动发现master宕机,进行自动切换slave > master。

Redis-Sentinel 主要功能

  • 监控:定期检测Redis 数据节点、其他 Sentinel 节点是否可达。
  • 通知:将故障转移的结果通知给应用方。
  • 故障转移:实现从节点晋升为主节点,并维护后续正确的主从关系
  • 配置提供:客户端在初始化的时候连接 Sentinel 节点集合,从中获取主节点信息。

多个 Sentinel 节点来共同判断故障,可以有效防止误判,同时如果个别 Sentinel 节点不可用,整个 Sentinel 节点集合依然是高可用的。

Redis-Sentinel 架构


基础架构

故障转移
多集群管理

Redis-Sentinel 配置

配置文件准备

# 创建目录
mkdir /data/2638{0..2}

# 26380节点
cat >/data/26380/sentinel.conf<<EOF
port 26380
dir "/data/26380"
logfile 'sentinel.log'
sentinel monitor mymaster 127.0.0.1 6380 2
sentinel down-after-milliseconds mymaster 5000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel auth-pass mymaster 123 
EOF


# 26381节点
cat >/data/26381/sentinel.conf<<EOF
port 26381
dir "/data/26381"
logfile 'sentinel.log'
sentinel monitor mymaster 127.0.0.1 6380 2
sentinel down-after-milliseconds mymaster 5000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel auth-pass mymaster 123 
EOF


# 26382节点
cat >/data/26382/sentinel.conf<<EOF
port 26382
dir "/data/26382"
logfile 'sentinel.log'
sentinel monitor mymaster 127.0.0.1 6380 2
sentinel down-after-milliseconds mymaster 5000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel auth-pass mymaster 123 
EOF

启动 redis-sentinel

redis-sentinel /data/26380/sentinel.conf &
redis-sentinel /data/26381/sentinel.conf &
redis-sentinel /data/26382/sentinel.conf &

检查

redis-cli -p 26380 -a 123 info sentinel

---------------------------------------
# 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=127.0.0.1:6380,slaves=2,sentinels=3
# sentinels=3  说明三个sentinels启动成功

Redis-Sentinel 测试

模拟6380(master)节点故障

redis-cli -p 6380 shutdown

# 查看6381节点,被去哪
	

role:master
connected_slaves:1

查看6381节点(被选为新master节点)

[root@db01 ~]# redis-cli -a 123 -p 6381 info replication
role:master
connected_slaves:1

查看6382节点(slave节点,指向了新master节点6381)

[root@db01 ~]# redis-cli -a 123 -p 6382 info replication
role:slave
master_host:127.0.0.1
master_port:6381

模拟6380节点恢复(作为slave节点自动恢复主从关系)

[root@db01 ~]# redis-cli -a 123 -p 6380 info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6381
posted @ 2020-05-10 17:25  OneLpc  阅读(424)  评论(0编辑  收藏  举报