[学习笔记 Day 01] Redis 基础:从入门到缓存、主从、分片集群的深入

介绍以及安装

如需了解可以移步到下面的文章中!

入门

特性:

类型键值数据库、非关系型数据库
数据关联非结构化
事物特性无关联
存储特征内存
扩展性水平

键值型、单线程(每个命令具备原子性)、低延迟、速度快、支持数据持久化、支持主从集群、分片集群、支持多语言客户端。

简要扩展:(Linux 安装)

安装依赖:

yum install -y gcc tcl

上传从官网下载的安装包并上传!

使用命令解压:

tar -zxvf redis.tar.gz

进入到解压目录并运行编译命令:

make && make install

默认的安装路径:

cd /usr/local/bin

Redis 服务启动

服务启动(默认启动)

redis-server

指定配置启动(后台启动)

目录:/usr/local/src/redis

备份配置文件:cp redis.conf redis.conf.bak

配置文件:vim redis.conf

# 改
bind 0.0.0.0                 # 改为任意的访问地址
daemonize yes                # 设置为可以后台访问
requirepass password         # 设置访问密码

# 其他
port 6379                    # 端口
dir .                        # 工作目录(日志、持久化等文件保存在此目录)
database 1                   # 数据库数量(默认 16)
maxmemory 512mb              # 使用最大内存
logfile "redis.log"          # 日志文件(默认为空)

启动(需要先进入到目录中):redis-server "redis.conf"

进程查看:ps -ef | grep redis

关闭 Redis:kill -9 进程号

设置为开机自启:vim /etc/systemd/system/redis.service

# 在 /etc/systemd/system/redis.service 加入内容
[Unit]
Descript = redis-server
After = network.target

[service]
Type = forking
ExecStart = /usr/local/bin/redis-server /usr/local/src/redis-6.2.6/redis.conf
PrivateTmp = true

[Install]
WantedBy = multi-user.target

重载系统服务:systemctl daemon-reload

启动:systemctl start redis / systemctl enable redis

Redis 客户端启动

redis-cli [option] [commands]

    option: -h 127.0.0.1         # 连接的 IP 地址(默认 127.0.0.1)
            -p 6379              # 端口号(默认 6379)
            -a password          # 连接密码

    commands: ping               # 心跳测试
              AUTH password      # 连接密码

图形化客户端(需要编译):

常见命令

数据结构:key => string

value:

-- 基本类型
string         "xxx"
Hash           {name:"mark" ,age:21}       -- 哈希表
List           [A -> B -> C -> D]          -- 集合
Set            {A ,B ,C}
SortedSet      {A:1 ,B:2 ,C:3}

-- 特殊类型
GEO            {A:(120.3 ,30.5)}           -- 地理坐标
BitMap         0110110101
HyperLog       0110111000

查看通用命令:help @generic

命令说明示例
KEYS查看符合模板的所有 key (模糊查询),
生产环境下不建议使用
KEYS name
— 结果:”lastname”,”rname”
KEYS a??
— 结果:”age”
KEYS *
— 结果:”lastname”,”rname”,”age”
DEL key删除键DEL name
DEL key1,key2,key3,…
— 返回执行的数量
MSET key value ...批量添加键MSET key1 vaule1 key2 value2 key3 value3 …
EXISTS key检查键是否存在
EXPIRE key time(s)设置键的有效期EXPIRE age 20
TTL key查看 key 的剩余时间
(-1:永久有效,-2:过期)

数据类型

  • String 类型:字符串类型
    • 其中 value 是字符串,也可以分为 3 类:(底层为字符串类型,最大空间不超过 512mb)
      • string:普通字符串
      • int:整数型
      • float:浮点型
    • 常见命令:
      • SET key value:添加或修改已经存在的 string 键值对
      • GET key:根据 key 获取 string 类型的键值对
      • MGET key1,key2,key3,...:批量获取多个键值对
      • INCR key:让一个整型 key 自增 1
      • INCRBY key step:让一个整型 key 自增 step
      • INCRBYFLOAT key step:让一个浮点型 key 自增 step
      • SETNX key value:如果 key 存在,则不添加,反之则添加一个 string 的键值对(同 SET key value
      • SETEX key time(s) value:添加一个 string 类型的键值对,并设置有效期(同 SET key value EX time(s)
    • 补充:
      • key 的结构:key1:key2:key3:...
  • Hash 类型(散列)
    • value 是一个无序字典
    • 常见命令:
      • HSET key field1 value1 [field2 value2,field3 value3,...]:添加或修改 hash 类型的 field 的值
      • HGET key field:获取 hash 类型的 field 值
      • HMSET key field1 value1 [field2 value2,field3 value3,...]:批量添加或修改(等价于 HSET)
      • HMGET key field1 field2 ...:批量获取
      • HGETALL key:获取 key 中的所有 field-value 值
      • HKEYS key:获取 key 中的所有 field 值
      • HVALS key:获取 key 中的所有 value
      • HINCRBY key field step:让 key 中的 field 自增长 step
      • HSETNX key field value:field 不存在添加,存在则不添加
  • List 类型
    • 可以看作是双向链表结构,既支持正向检索也支持反向检索
    • 特征:有序,元素可重复,插入、删除快查询数据一般
    • 常见命令:
      • LPUSH key element:向表左侧插入一个或多个元素
      • LPOP key count:移除并返回表左侧第 count 个元素,没有则返回 null
      • RPUSH key element:向表右侧插入一个或多个元素
      • RPOP key count:移除并返回表右侧第 count 个元素,没有则返回
      • LRANGE key start end:返回一段角标范围内的所有元素
      • BLPOP / BRPOP key time(s):与 LPOP / RPOP 类似,只不过在没有元素时等待指定时间,而不是返回 null
  • Set 类型
    • 可以看作是 value 为 null 的 HasMap
    • 特征:无序,元素不可重复,查找快,支持交集、并集、差集等
    • 常见命令
      • SADD key member ...:添加一个或多个元素
      • SREM key member ...:移除一个或多个元素
      • SCARD key:返回元素个数
      • SISMEMBER key number:判断某个元素是否存在
      • SINTER key1,key2 ...:求交集
      • SDIFF key1,key2 ...:求差集
      • SUNION key1,key2 ...:求并集
  • SortSet 类型:
    • 每个元素都带有一个 score 属性(基于排序),底层是一个跳表(skipList)加 Hash 表
    • 特性:可排序,元素不重复,查询速度快
    • 常见命令:(默认升序,降序:ZREV)
      • ZADD key score member ...:添加一个或多个元素,如果存在则更新 Score 值
      • ZREM key member:删除一个或多个元素
      • ZSCORE key member:获取指定元素的 score 值
      • ZRANK key member:获取指定元素的排名
      • ZCARD key:获取元素的个数
      • ZCOUNT key min max:统计 score 值范围内的元素个数
      • ZINCRBY key step member:让指定元素自增 step
      • ZRANGE key min max:排序后,获取指定排名范围内的数据
      • ZRANGEBYSCORE key min max:排序后,获取指定范围内的数据
      • ZDIFF key1,key2 ...:求差集
      • ZINTER key1,key2 ...:求交集
      • ZUNION key1,key2 ...:求并集

分布式缓存

持久化 RDB

数据快照,把内存中的所有文件数据都记录到磁盘中,路径为运行目录。

命令:

-- 保存数据,由主进程执行(会阻塞所有命令)
save

-- 后台保存数据,由子进程执行
bgsave

时机:Redis 停机时会执行一次

Redis 内部有触发机制,可以在 redis.conf 中找到,如下:

save 900 1              # 900秒内有一个 key 改变,则执行 bgsave,如果是 save 则禁用

# 其他配置
rdbcompression yes      # 是否压缩(不建议,会消耗 cpu)
dbfilename dump.rdb     # RDB 文件名称

bgsave 开始会 fork 主进程得到子进程(主进程 == 共享数据 ==> 子进程),完成 fork 后读取并写入 RDB 文件。

图片[1]-[学习笔记 Day 01] Redis 基础:从入门到缓存、主从、分片集群的深入-资源刺客

在主进程进行读时,访问共享内存

在子进程进行读时,会先拷贝一份(在这份数据上进行写)

缺点:

  • 两次 RDB 之间写数据会有丢失数据的风险
  • fork 子进程、压缩、写出会比较耗时

AOF 持久化

处理每一个写命令会记录在 AOF 文件(看日志文件)

redis.conf 文件配置:

appendonly yes
appendfilename "appendonly.conf"      # 文件名
appendfsync always                    # 执行频率(always:执行一次写一次、everysec:先放入缓冲区,再 1 秒写一次(默认)、no:先放入缓冲区、由操作系统决定何时写入 AOF)

appendfysnc 各项区别:

选项刷盘时机优点缺点
always同步可靠性高,几乎不丢失性能影响大
everysec每秒性能适中最多丢失 1 秒的数据
no操作系统控制性能最好可靠性差,可能丢失大量数据
BGREWRITEAOF

使用 redis.conf 进行配置:

auto-aof-rewrite-percentage 100      # 文件大小增长多少则触发重写

auto-aof-rewrite-min-size 64mb       # 文件体积最大多少以上触发重写

RDB 与 AOF 区别:

RDBAOF
持久化方式定时对整个内存快照记录每一次记录的执行命令
数据完整性不完整,两次之间会丢失相对完整,取决于刷盘策略
文件大小会压缩,文件体积会减少记录命令,文件体积很大
宕机恢复速度很快
数据恢复优先级低,数据完整性不如 AOF高,数据完整性更高
系统资源占用高,大量 CPU 和内存消耗
使用场景可容忍数分钟的数据丢失,追求更快的启动速度对数据完整性要求较高

Redis 主从

  • 准备实例和配置
# 创建不同的服务(运行目录)
mkdir 7001 7002 7003
# 将原始配置文件拷贝到上述的 3 个文件夹中
echo 7007 7002 7003 | xargs -t -n | cp redis-6.2.4/redis.conf
# 该配置文件端口、文件目录(分别对应三个文件的)
sed -i -e 's/6379/7001/g' 's/dir .\//dir \/dir \/temp\/7001\//g' 7001/redis.conf

sed -i -e 's/6379/7002/g' 's/dir .\//dir \/dir \/temp\/7002\//g' 7002/redis.conf

sed -i -e 's/6379/7003/g' 's/dir .\//dir \/dir \/temp\/7003\//g' 7003/redis.conf
# 修改实例 IP (每个文件都需加)
replica-announce-ip x.x.x.x
  • 将三个服务都启动
cd 7001
redis-server "redis.conf"

cd 7002
redis-server "redis.conf"

cd 7003
redis-server "redis.conf"
  • 开启主从关系

在 Redis.conf 中添加:

slaveof <master-ip> <masterport>

# master-ip:主节点 IP
# masterport:从节点 port

数据同步原理

首次同步:

图片[2]-[学习笔记 Day 01] Redis 基础:从入门到缓存、主从、分片集群的深入-资源刺客

首次同步概念:

  • ReplicationID:数据集标记
  • offset:偏移量

slave 重启后同步(增量同步):

图片[3]-[学习笔记 Day 01] Redis 基础:从入门到缓存、主从、分片集群的深入-资源刺客

优化 Redis 主从集群:

  • 在 master 中配置 repl_diskless_sync yes 启用无磁盘复制,避免全量同步时的磁盘 IO(网络好,磁盘慢的情况)
  • Redis 单节点上的内存占用不要太大,减少 RDB 倒置过多的磁盘 IO
  • 适当提高 repl_baklog 文件的大小,发现 slave 宕机时尽快故障恢复
  • 限制一个 master 上的 slave 节点数量,如 slave 太多,则采用“主 – 从 – 从”

Redis 哨兵

监控集群,自动故障恢复、故障转移

原理:每秒发生命令 PING,如果指定数量的 sentinel 都认为下线,才会觉得该节点下线

选新的 master 节点的标准步骤:

  • 如果超过指定值 (down-after-milliseconds * 10) 则会排除该节点
  • 判断 slave 节点的 slave-priority 值,越小优先级越高,为 0 则不参选
  • 如果 slave-priority 一样,则判断节点的 offset 值,越大数据越新,优先级越高
  • 最后判断 slave 的运行 id 大小,越小优先级越高

故障转移:

图片[4]-[学习笔记 Day 01] Redis 基础:从入门到缓存、主从、分片集群的深入-资源刺客

搭建哨兵集群

  • 准备实例和配置
# 分别创建 3 个文件,每个文件夹代表一个 sentinel 节点
mkdir s1 s2 s3
  • 添加 sentinel.conf 文件(s1 文件夹下面添加)
port 27001                                            # sentinel 的实例端口
sentinel announce-ip x.x.2.4                          # sentinel 的实例地址
sentinel moniter mymaster x.x.2.4 7001 2              # 配置主 sentinel 节点信息:ip地址 主节点端口 选举值
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
dir "/tmp/s1"
  • 然后将 s1/sentinel.conf 文件拷贝到另外两个文件夹中
echo s2 s3 | xargs -t -n | cp s1/sentinel.conf
  • 分别修改拷贝的文件信息
sed -i -e 's/27001/27002/g' -e 's/s1/s2/g' s2/sentinel.conf

sed -i -e 's/27001/27003/g' -e 's/s1/s3/g' s3/sentinel.conf
  • 启动集群
redis-sentinel s1/sentinel.conf

redis-sentinel s2/sentinel.conf

redis-sentinel s3/sentinel.conf

Redis 的分片集群

目的:

  • 高可用、高并发读
  • 海量数据存储问题
  • 高并发写的问题

特征:

  • 集群中有多个 master (各保存不同的数据)
  • 每个 master 可有 slave 节点
  • master 之间通过 PING 检测相互的状态
  • 客户端可访问集群任意节点,最终会被转移到正确节点

搭建分片集群

  • 配置和创建实例
    • 创建一个的 redis.conf 文件
port 6379
cluster-enabled yes                           # 开启集群
cluster-config-file /tmp/6379/nodes.conf      # 集群配置文件名称(无需配置和维护)
cluster-node-timeout 5000                     # 节点心跳失败的超时时间
dir /tmp/6379                                 # 持久化文件路径(工作目录)
bind 0.0.0.0
daemonize yes
replica_announce-ip x.x.x.x
protected-mode no                             # 保护模式
database 1                                    # 数据库数量
logfile /tmp/6379/run.log
  • 将该配置文件复制到各目录下
echo 7001 7002 7003 8001 8002 8003 | xargs -I {} -t sed -i 's/6379/{}/g'
  • 批量修改每个 redis.conf 文件
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I {} -t sed -i 's/6379/{}/g' {}/redis.conf
  • 批量启动所有服务
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I {} -t redis-server {}/redis.conf
  • 批量关闭所有服务
printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I {} -t redis-cli {} shutdown

创建集群

  • Redis 5.0 之前
yum -y install zlib ruby rubygems

gem install redis

管理集群:

cd /tmp/redis-6.2.4/src

./redis-trib.rb create -replicas 1 x.x.x.1:7001 x.x.x.2:7002 x.x.x.3:7003 x.x.x.4:8001 x.x.x.5:8002 x.x.x.6:8003
  • Redis 5.0 过后
redis-cli --cluster create --cluster-replicas 1 x.x.x.1:7001 x.x.x.2:7002 x.x.x.3:7003 x.x.x.4:8001 x.x.x.5:8002 x.x.x.6:8003

# redis-cli --cluster => 或 ./redis-trib.rb
# create => 创建集群
# -cluster-replicas 1 => 或 --replicas 1(主从 1:1,6个节点,前面 3 个为主)

查看集群状态:

redis-cli -p 7001 cluster nodes

散列插槽

Redis 会把每一个 master 节点映射到 0~16383 个插槽上

扩展:启动集群

redis-cli -c -p 7003

# -c:集群模式

集群伸缩

向集群中添加新的节点:

redis-cli --cluster add-node <ip>:<port> <集群中存在的IP>:<port>

# <ip>:要添加的 IP 地址
# <port>:端口号

分配插槽值:

redis-cli -cluster reshard <要分割值的 IP>:<port>

故障转移

关闭 Redis 实例:

redis-cli -p port shutdown

Redis 会自动实现故障转移

利用 cluster failover 命令:cluser failover

图片[5]-[学习笔记 Day 01] Redis 基础:从入门到缓存、主从、分片集群的深入-资源刺客

手动 Failover 支持三种模式:

  1. 缺省,默认流程
  2. force :省略了对 offset 的一致校验
  3. takeover:从标记自己为 master 开始

多级缓存

充分利用请求处理的每个环节,分别添加缓存。

  • 分布式缓存:如 Redis
    • 优点:存储容量大,可靠性好,可以在集群间共享
    • 缺点:访问缓存有网络开销
    • 场景:缓存数据量大,可靠性性要求高,需要在集群间共享
  • 本地进程缓存:由于是存储在内存中,数据获取较快
    • 优点:读取本地内存,没有网络开销,速度快
    • 缺点:存储容量有限,可靠性较低、无法共享
    • 场景:性能要求较高、缓存数据量较小

https://wp.itdka.cn/1484.html
THE END
喜欢就支持一下吧
点赞15 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容