• 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 {password}

    配置方法

    [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
    
  • 相关阅读:
    iostream与iostream.h的区别
    [HAOI2011]向量
    [POI2011]Temperature
    [洛谷2839/国家集训队]middle
    [TJOI2013]松鼠聚会
    [HNOI2015]接水果
    [BZOJ3772]精神污染
    [BZOJ3251]树上三角形
    [ZJOI2011]道馆之战
    [SDOI2013]森林
  • 原文地址:https://www.cnblogs.com/lpcsf/p/12864239.html
Copyright © 2020-2023  润新知