03.Redis高级篇-企业实战

目录

  • Redis实践
    • [1. Redis监控](#1. Redis监控)
      • [1.1 系统自带监控](#1.1 系统自带监控)
        • [(1) Info](#(1) Info)
        • [(2) Monitor](#(2) Monitor)
        • [(3) latency](#(3) latency)
        • [(4) Intrinsic latency](#(4) Intrinsic latency)
        • [(5) Latency monitor](#(5) Latency monitor)
        • [(6) Slow log](#(6) Slow log)
      • [1.2 Prometheus-Redis-exporter 监控 多实例监控部署](#1.2 Prometheus-Redis-exporter 监控 多实例监控部署)
      • [1.3 redis-stat(作业)](#1.3 redis-stat(作业))
    • 2、Redis-benchmark压测
      • [2.1 介绍](#2.1 介绍)
      • [2.2 参数](#2.2 参数)
      • [2.3 模拟](#2.3 模拟)
      • [2.4 结果分析](#2.4 结果分析)
    • [3. Redis应用问题解决](#3. Redis应用问题解决)
    • 4、Redis运维问题及优化案例
      • [(1) 数据类型选择不合理](#(1) 数据类型选择不合理)
      • [(2) 过期key订阅](#(2) 过期key订阅)
      • [(3) 大key问题](#(3) 大key问题)
      • [(4) 数据倾斜](#(4) 数据倾斜)
      • [(5) 流量倾斜](#(5) 流量倾斜)
      • [(5) redis慢日志](#(5) redis慢日志)
      • [(6) 波动的响应延迟](#(6) 波动的响应延迟)
      • [(7) 删除数据后,内存占用率无法下降](#(7) 删除数据后,内存占用率无法下降)
      • [(8) 脑裂](#(8) 脑裂)
    • [5. redis shake](#5. redis shake)
      • [5.1 RedisShake能做什么](#5.1 RedisShake能做什么)
      • [5.2 RedisShake基本原理](#5.2 RedisShake基本原理)
        • [(1) 功能](#(1) 功能)
        • [(2) 基本同步模式](#(2) 基本同步模式)
        • [(3) sync模式数据流图](#(3) sync模式数据流图)
      • [5.3 数据同步示例](#5.3 数据同步示例)
      • [5.4 redis-shake注意事项](#5.4 redis-shake注意事项)
    • 6、Redis备份恢复
    • [7. Redis企业使用规范](#7. Redis企业使用规范)
    • [8. cachedoud](#8. cachedoud)
      • [(1) CacheCloud 是什么?](#(1) CacheCloud 是什么?)
      • [(2) 部署](#(2) 部署)
      • [(3) 配置修改](#(3) 配置修改)
      • [(4) 添加机器](#(4) 添加机器)
      • [(5) 导入应用](#(5) 导入应用)

Redis实践

1. Redis监控

1.1 系统自带监控

(1) Info
bash 复制代码
redis-cli info
# 获取所有信息
> info
# 获取内存相关信息,info 可以一次性获取所有的信息,也可以按块取信息
> info memory
# 获取复制相关信息
> info replication

# Info 指令显示的信息非常繁多,分为 9 大块,每个块都有非常多的参数,这 9 个块分别是:
#(如果想要了解所有的参数细节,请参考阅读:https://redis.io/commands/info)
  1. Server 服务器运行的环境参数
  2. Clients 客户端相关信息
  3. Memory 服务器运行内存统计数据
  4. Persistence 持久化信息
  5. Stats 通用统计数据
  6. Replication 主从复制相关信息
  7. CPU CPU 使用情况
  8. Cluster 集群信息
  9. KeySpace 键值对统计数量信息

比较重要的参数指标

复制代码
instantaneous_ops_per_sec:789 # ops_per_sec: operations per second, 也就是每秒操作数
connected_clients:124 #正在连接的客户端数量,client list列出所有的客户端连接
rejected_connections:0 #因为超出最大连接数限制而被拒绝的客户端连接次数
maxclients:10000 #最大连接数
maxmemory_human:100.00M #redis设置的最大内存
used_memory_human:827.46K #内存分配器(jemalloc)从操作系统分配的内存总量
used_memory_rss_human:3.61M #操作系统看到的内存占用,top命令看到的内存
used_memory_peak_human:829.41K #Redis 内存消耗的峰值
repl_backlog_size:1048576 # 复制积压缓冲区大小
sync_partial_err:0 #半同步失败次数

配合linux下的watch命令,实时监测redis的内存开销和吞吐量,用作流量

bash 复制代码
watch -n 1 -d "redis-cli -p 6400 info |grep -e connected_clients -e used_memory_human -e used_memory_peak_human -e instantaneous -e evicted_keys"
(2) Monitor
bash 复制代码
#monitor的开启,会很大程度影响redis本身的性能。监测redis运行过程中的每个命令的信息。
redis-cli -p 6400 monitor
(3) latency
bash 复制代码
#ping操作,检测server和client间的网络延时,一般都是1ms以内
redis-cli --latency
(4) Intrinsic latency
bash 复制代码
#redis的延时基准(命令本身的耗时),运行命令
redis-cli --intrinsic-latency 100
(5) Latency monitor
bash 复制代码
#redis运行过程中,可以对超出某个时间阈值的命令进行监控。开启监测的方式如下:
CONFIG SET latency-monitor-threshold 100 #ms

#监测系统运行过程中fork时间大于10ms的fork latency。
latency history fork
(6) Slow log
bash 复制代码
#开启记录latency大于100ms的命令和最大保留1000条slowlog
CONFIG SET slowlog-log-slower-than 100 #单位微妙,执行时间大于该值的query才会被记录,默认10ms
CONFIG SET slowlog-max-len 1000 #慢查询最大的条数,超过则最早的被删除(FIFO队列)

#查看slowlog总条数
127.0.0.1:6379> SLOWLOG_LEN
(integer) 4

#读取
/*
1)日志的标识 id
2)发生的时间戳
3)命令耗时
4)执行的命令和参数
*/

127.0.0.1:6379> SLOWLOG GET
1)1)(integer)1 #唯一性(unique)的日志标识符,只有在Redis服务器重启的时候才会重置,可以避免对日志的重复处理(比如邮件通知)
2)(integer)1559237232 #被记录命令的执行时间点,以Unix时间戳格式表示
3)(integer)13 #命令耗时,以微秒为单位
4)1)"set" #执行的命令,以数组的形式排列
2)"aaa"
3)"bbb"

1.2 Prometheus-Redis-exporter 监控 多实例监控部署

bash 复制代码
wget https://github.com/oliver006/redis_exporter/releases/download/v1.50.0/redis_exporter-v1.50.0.linux-amd64.tar.gz
tar zxvf redis_exporter-v1.50.0.linux-amd64.tar.gz
mv redis_exporter-v1.50.0.linux-amd64 redis_exporter
cd redis_exporter
./redis_exporter --help
# -namespace string    #指标名字
# -redis.addr string    #redis地址,多实例监控参数
# -redis.password string   #redis密码监控
# -redis.user string    #6.0版本ACL特性
# -web.listen-address string   #默认端口 9121
# -web.telometry-path string   #指标暴露地址,默认 /redis-metrics,即 http://192.168.9.78:9090/metrics
  • 多实例配置redis-exporter 监控步骤
bash 复制代码
# 1.安装promethus+grafana(略)
# 2.启动exporter
nohup ./redis_exporter -redis.addr= _web.listen-address:9121 & #观察指标
curl http://192.168.9.78:9121/metrics

# 3.配置文件,prometheus.yml中加入job
cat prometheus.yml
- job_name: 'redis_exporter_targets'
  static_configs:
  - targets:
    - redis://192.168.9.78:6400
    - redis://192.168.9.78:6410
    - redis://192.168.9.78:6411
  metrics_path: /scrape
  relabel_configs:
  - source_labels: [_address_]
    target_label: __param_target
  - source_labels: [_param_target]
    target_label: instance
  - target_label: __address_
    replacement: 192.168.9.78:9121

- job_name: 'redis_exporter'
  static_configs:
  - targets:
    - 192.168.9.78:9121

##热加载prometheus
curl -X POST 192.168.9.78:9090/-/reload
##查看指标
http://192.168.9.78:9090/targets

# 4. 配置dashboard, 导入Dashboard
# 地址:https://grafana.com/oss/prometheus/exporters/redis-exporter/?tab=dashboards
# 在grafana中导入json模板

1.3 redis-stat(作业)

  • 轻量级redis服务监控运行,基于INFO信息,比monitor(影响性能)要友好
  • 分为终端命令行和可视化web界面两种
  • 最佳场景:压测,实时监控

使用步骤

网址: https://github.com/junegunn/redis-stat/

  1. 安装
bash 复制代码
# 安装ruby
sudo yum install ruby
sudo yum install ruby-devel
# gem update --system -- 更新到最新版

# 移除默认镜像地址并更换国内镜像地址,
gem sources --remove https://rubygems.org -a https://gems.ruby-china.com
# 更换国内镜像地址 可选镜像
gem sources -a https://gems.ruby-china.com
gem sources --add https://mirrors.tuna.tsinghua.edu.cn/rubygems/
# 查看
gem sources -l

# gem安装
gem install redis-stat
# 源码方式
wget https://github.com/junegunn/redis-stat/releases
  1. 使用
bash 复制代码
#黑屏命令行监控
./redis-stat 192.168.9.78:6400 192.168.9.78:6411 5

#web图形监控
./redis-stat 192.168.9.78:6400 192.168.9.78:6411 --server=9000 5 --daemon
# 访问地址: http://192.168.9.78:9000/

使用java版本

bash 复制代码
# 使用java版本,下载jar包
# https://github.com/junegunn/redis-stat/releases/download/0.4.14/redis-stat-0.4.14.jar
# 命令行监控,执行jar包
java -jar redis-stat-0.4.14.jar --server 192.168.9.78:6400 192.168.9.78:6411 5

# 使用web页面监控,
java -jar redis-stat-0.4.14.jar 192.168.9.78:6400 192.168.9.78:6411 5 --server=9000
# 访问地址: http://192.168.9.78:9000/

Dashboard示例

复制代码
time     us sy cl bcl mem   rss   keys cmd/s exp/s evt/s hit%/s hit/s mis/s ad/ca
00:30:55 0  0  1  0   1.74MB 12.9MB 12  0.20 0     0     -      0    0     1.49MB
...

Instance information示例

复制代码
redis_version     6.2.12
redis_mode       standalone
process_id       93226
uptime_in_seconds 389061
uptime_in_days   4
role            master
connected_slaves 0
ad_enabled       1

2、Redis-benchmark压测

2.1 介绍

redis-benchmark是Redis自带的基准性能测试工具

redis-benchmark测试cluster集群实例时需要加 --cluster 参数

2.2 参数

bash 复制代码
-h <hostname> 指定服务器主机名(默认 127.0.0.1)
-p <port> 指定服务器端口(默认 6379)
-s <socket> 指定服务器 socket
-a <password> Redis 认证密码
-c <clients> 指定并发连接数(默认 50)
-n <requests> 指定请求数(默认 100000)
-d <size>    以字节的形式指定 SET/GET 值的数据大小(默认 2)
--dbnum <db>  选择指定的数据库号(默认 0)
-k <boolean> l=keep alive 长链接, 0=reconnect(默认 1)每次请求重新连接
-r <keyspacelen> SET/GET/INCR 使用随机 key,SADD 使用随机值
-P <numreq>    通过管道传输 <numreq> 请求,代表每个请求pipeline的数据量(默认为1)
-q    仅仅显示redis-benchmark的requests per second信息,
-t <tests>    可以对指定命令进行基准测试 例如: -t get,set
--csv 以 CSV 格式输出

2.3 模拟

50个客户端同时请求Redis,总共1万个请求,

bash 复制代码
/usr/local/redis/bin/redis-benchmark -p 6400 -p 10 -c 50 -d 100 -n 10000 -t get

2.4 结果分析

bash 复制代码
# redis-benchmark -p 6400 -p 10 -c 50 -d 100 -n 10000 -t get
===== MSET (10 keys) ====
10000 requests completed in 0.13 seconds #总共1万次,0.13秒完成
50 parallel clients #50并发
100 bytes payload #每个请求100字节
keep alive: 1

97.81% <= 1 milliseconds #97.81%的命令执行时间小于1毫秒
99.23% <= 2 milliseconds
100.00% <= 2 milliseconds

Summary:
    throughput summary: 476190.47 requests per second #每秒可以处理476190.47次get请求
    latency summary (msec):
    avg min p50 p95 p99 max
    0.845 0.232 0.791 1.127 2.335 2.455

3. Redis应用问题解决

① 缓存穿透:大量请求根本不存在的key

② 缓存雪崩:redis中大量key集体过期

③ 缓存击穿:redis中一个热点key过期(大量用户访问该热点key,但是热点key过期)

④ mysql与redis双写不一致:

3.1 缓存穿透

场景描述

缓存穿透:是指查询一个根本不存在的数据,缓存层和存储层都不会命中

访问 → 请求web服务 → 访问缓存获取不存在数据 → 数据库查询不存在数据 → 无法同步缓存

解决方案

  1. 缓存空对象
  2. 布隆过滤器拦截
    布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。
    将所有可能存在的数据信给到一个足够大的bitmaps中,一个一定不存在的数据会被 这个bitmaps拦截掉,从而避免了对底层存储系统的查询压力。
  3. 对前端查询条件加密,比如商品id,使用md5加密,无规律,前端无法模拟;
  4. 小批量数据设置可访问的名单(白名单)
    使用bitmaps类型定义一个可以访问的名单,名单id作为bitmaps的偏移量,每次访问和bitmap里面的id进行比较,如果访问id不在bitmaps里面,进行拦截,不允许访问。
  5. 进行实时监控:当发现Redis的命中率开始急速降低,需要排查访问对象和访问的数据,和运维人员配合,可以设置黑名单限制服务

3.2 缓存击穿

场景描述

key对应的数据存在,但在redis中过期,此时若有大量并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回收到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。

访问 → 请求web服务 → 访问缓存 key过期 → 瞬时访问量过大

解决方案

key可能会在某些时间点被超高并发地访问,是一种非常"热点"的数据。这个时候,需要考虑一个问题:缓存被"击穿"的问题。
解决问题

  1. 预先设置热门数据:在redis高峰访问之前,把一些热门数据提前存入到redis里面,加大这些热门数据key的时长
  2. 设置热点数据永远不过期
  3. 使用互斥锁

3.3 缓存雪崩

场景描述

大量热点key同时过期 或者 缓存服务故障,导致请求无法命中缓存,而是直接打到DB,这个时候大并发的请求可能会瞬间把后端DB压垮。

缓存雪崩与缓存击穿的区别在于这里针对很多key缓存,前者则是某一个key

正常访问:访问 → 请求web服务 → 分发到该服务器 → 访问缓存 → 定期更新数据

缓存失效瞬间:访问 → 请求web服务 → 分发到该服务器 → 访问缓存 → 数据批量过期 → 更新失效

解决方案

缓存失效时的雪崩效应对底层系统的冲击非常可怕!
解决方案

  1. 构建多级缓存架构:nginx缓存 + 本地缓存 + redis缓存
  2. 考虑用队列或着锁的方式,保证缓存单线程写,但这种方案可能会影响并发量
  3. 双key策略,主key设置过期时间,备key不设置过期时间,当主key失效时,直接返回备key值。
  4. 避免给大量的数据设置相同的过期时间
    比如我们可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。
  5. 服务降级
  6. 业务系统中实现服务熔断或请求限流机制

3.4 MySQL与Redis双写一致性方案

(1)一致性

我们在这里说的一致性,是redis和MySQL数据的一致性。

一致性有三种模型:

  • 强一致性
  • 弱一致性
  • 最终一致性
(2)缓存模式
  • Cache-Aside Pattern (旁路缓存模式)
  • Read-Through/Write through(读取透写模式)
  • Write behind (写后模式)

Cache-Aside(旁路缓存)

  • Cache-Aside读流程

    1. 读的时候,先读缓存,缓存命中的话,直接返回数据
    2. 缓存没有命中的话,就去读数据库,从数据库取出数据,放入缓存后,同时返回响应
  • Cache-Aside写流程

    1. 更新数据库
    2. 删除缓存。
      如果写请求更新数据库后异常了,没有删除缓存,就会造成缓存和数据库里的不一致。

Read-Through/Write-Through(读写穿透)

  • Read-Through读流程

    1. 从缓存读取数据,读到直接返回
    2. 如果读取不到的话,从数据库加载,写入缓存后,再返回响应。
      Read-Through实际只是在Cache-Aside之上进行了一层封装,它会让程序代码变得更简洁,同时也减少数据源上的负载。
  • Write-Through 写流程

    Write-Through模式下,当发生写请求时,也是由 缓存抽象层 完成数据源和缓存数据的更新。

Write behind (异步缓存写入)

Write-Behind模式下,应用程序在写入数据时首先将数据写入缓存,然后异步地将数据写入数据源。

相同:都是由Cache Provider来负责缓存和数据库的读写

不同: Read/Write Through是同步更新缓存和数据的,Write Behind则是只更新缓存,不直接更新数据库,通过批量异步的方式来更新数据库。

这种方式下,缓存和数据库的一致性很强,对一致性要求高的系统要谨慎使用。但是它适合频繁写的场景,MySQL的InnoDB Buffer Pool机制就使用到这种模式。

(3)不一致问题分析

A. 先写数据库再更新缓存不一致问题

更新缓存相对于删除缓存的劣势:

  • 如果写入的缓存值,是经过复杂计算才得到的话,更新缓存频率高的话,就浪费性能了;
  • 在写数据库场景多、读数据场景少的情况下,数据很多时候还没被读取到,又被更新了,这也浪费了性能。

B. 先删缓存,读的时候再写不一致问题

缓存和数据库的数据不一致。缓存保存的是老数据,数据库保存的是新数据。

(4)不一致问题解决

缓存延时双删

写请求 → 删除缓存 → 更新数据库 → 删除缓存

删除缓存重试机制

写请求 → 应用程序 → 1.更新数据库 → 数据库

→ 2.删除缓存失败 → 缓存

→ 3.删除失败的key → 消息队列 → 4.要删除的key拉出来 → 5.重试删除操作

读取binlog异步删除缓存

binlog → canal → mq ACK机制确认更新消息,删除缓存

4、Redis运维问题及优化案例

(1) 数据类型选择不合理

  1. 选择合适的类型

    当一个可以聚合的内容分开存储时,总共占用了(64+57+61)=182字节,改为hash存储时,占用了98字节。

  2. 压缩列表的条件:"列表中元素数量<512个" && "列表中所有字符串对象都不足64字节"

示例

bash 复制代码
local0>set user:1000:login "login"
"OK"
local1>set user:1000:quota "2000"
"OK"
local2>set user:1000:info "xxx"
"OK"
local3>set user:1000 login "login" quota "2000" info "xxx"
"3"
local4>memory usage user:1000:login
"64"
local5>memory usage user:1000:quota
"57"
local6>memory usage user:1000:info
"61"
local7>memory usage user:1000
"98"

(2) 过期key订阅

现象

监听过期事件处理业务,如订单30分钟过期,因为程序没有再访问master,没有触发删除,导致系统订单一直未关闭,库存未释放。

redis内部机制

redis产生expired的时间为过期key被删除的时候,而不是ttl变为0的时候。

代码在:notifyKeyspaceEvent (NOTIFY_EXPIRED, "expired", key.db->id);

  1. __keyspace@db__:key expired
  2. __keyevent@db__:expired key
    redis订阅过期事件是订阅的 __keyevent@db__:expired

结论

当一个键过期时,Redis并不会主动通知订阅者。redis产生expired的事件为过期key被删除的时候,而不是ttl变为0的时候。而删除是由两种过期键删除策略完成的,一种是定期删除,另一种是惰性删除。会在适当的时候自动删除过期的键,也有可能不会触发删除。这就导致无法收到过期事件通知。从而引发生产事故。

(3) 大key问题

key过大会引起以下的问题

  • 占用网络IO和cpu,阻塞,比如有的key里存储十几MB的数据,多次查询,会阻塞其他的操作请求;
  • 内存挤占过多,甚至会把未失效的清掉,比如自己用zset做的限流、数据没有及时删除,导致占用内存过多;
  • del删除也会阻塞(使用异步删除unlink)

如何发现大key?

  • 实时检测:通过redis-cli --bigkeys检测
  • 离线检测:通过redis-rdb-tools工具对备份的rdb进行分析

redis-rdb-tools工具

redis-rdb-tools 是一个 python 的解析 rdb 文件的工具,在分析内存的时候,我们主要用它生成内存快照。

  1. 生成rdb文件

  2. 分析rdb文件,并将结果写入到csv文件中

    bash 复制代码
    rdb -c memory dump.rdb > dump-rdb.csv

    输出字段说明:

    复制代码
    database : key在redis的db
    type : key类型
    key : key值
    size_in_bytes : key的内存大小(byte)
    encoding : value的存储编码形式
    num_elements : key中的value的个数
    len_largest_element : key中的value的长度
    expiry : key过期时间
  3. '直接分析csv文件获取大key' or '将csv文件的数据导入到mysql数据库进行分析'

解决并避免

  • 异步删除
  • 选择合适的数据库
  • 选择合适的数据结构

(4) 数据倾斜

现象

redis cluster大量的key路由到其中一个master节点,导致该节点cpu、内存、qps升高

数据倾斜的原因

  1. 大key的出现
  2. 数据的写入机制,一般都是hash后不均匀出现的
  3. 数据迁移或扩容

解决

  1. 排查集群中是否存在大key,对bigkey拆分;
  2. 将数据量大的slot迁移,迁移一部分到其他master节点;
  3. 热点数据,利用分片算法的特性,对key进行打散处理

(5) 流量倾斜

流量倾斜一般是指redis集群中某个节点的流量远远大于平均流量值。

原因

  • 实例上存在热点数据

如何解决避免

  • 只读的热点数据:热点数据复制多份,每一个数据副本的 key 中增加一个随机前缀,让其被映射到不同的 Slot 中
  • 有读有写热点数据:升配

(5) redis慢日志

我们在分析redis变慢的时候,除了看cpu,看io,还有一种情况,就是啥都没问题,就是慢。那我们可以看看redis的慢日志。

redis的慢日志是redis提供的一个简单的慢命令统计记录功能,它会把命令执行时间超过slowlog-log-slower-than纪录到一个列表中,该列表通过slowlog-max-len控制长度。

配置

bash 复制代码
- 设置20000微妙
config set slowlog-log-slower-than 20000
- 设置保留1000条
config set slowlog-max-len 1000
config rewrite

示例

bash 复制代码
[root@OPS-9-78 ~]# redis-cli -p 6400
# 设置20000微妙
127.0.0.1:6400> config set slowlog-log-slower-than 20000
OK
# 设置保留1000条
127.0.0.1:6400> config set slowlog-max-len 1000
OK
127.0.0.1:6400> config rewrite
OK
# 查看慢日志
127.0.0.1:6400> slowlog get 1
1) 1) (integer) 1
   2) (integer) 1686971278
   3) (integer) 108129
   4) 1) "config"
   2) "rewrite"
   5) "127.0.0.1:49489"
   6) ""
# 查看日志列表的长度
127.0.0.1:6400> slowlog len
(integer) 2
# slowlyg 重置
127.0.0.1:6400> slowlog reset
OK
127.0.0.1:6400> slowlog len
(integer) 0

(6) 波动的响应延迟

redis客户端访问redis经过了网络,loop排队,命令执行,这三块都有可能导致redis server的响应延迟。

我们这节重点分析下loop排队中的延迟。

怎么查看延迟?

第一种方式

Redis 2.6版本的时候,引入了一个看门狗(watchdog)工具,这个工具可以用于诊断redis的延迟问题。

watchdog 只是用来调试程序的,会阻塞server,耗时会比较高,生产不要使用。

bash 复制代码
-- 设置延迟间隔时间
127.0.0.1:6400> CONFIG SET watchdog-period 300
OK
-- 关闭watchdog
127.0.0.1:6400> CONFIG SET watchdog-period 0

第二种方式

redis从 2.8.7 版本开始,redis-cli 命令提供了 -intrinsic-latency 选项,可以用来监测和统计测试期间内的最大延迟,这个延迟可以作为 Redis 的基线性能

bash 复制代码
[root@OPS-9-78 ~]# redis-cli -p 6400 --intrinsic-latency 120
Max latency so far: 1 microseconds.
Max latency so far: 7 microseconds.
Max latency so far: 41 microseconds.
Max latency so far: 42 microseconds.
Max latency so far: 49 microseconds.
Max latency so far: 98 microseconds.
Max latency so far: 341 microseconds.
Max latency so far: 818 microseconds.
Max latency so far: 1244 microseconds.
Max latency so far: 1621 microseconds.

1621249297 total runs (avg latency: 0.0740 microseconds / 74.02 nanoseconds per run).
Worst run took 21900x longer than the average latency.

cpu架构对redis性能的影响

redis是典型的cpu密集型应用,cpu的性能对redis的影响还是比较大的。

  • 1个cpu处理器一般有多个运行核心,一个运行核心称为一个物理核,每个物理核都可以运行程序
  • 每个物理核拥有私有的一级缓存(Level 1 cache 包括一级指令缓存和一级数据缓存)访问延迟在10ns,以及私有的二级缓存(Level 2 cache 访问延迟在100ns)
  • 一个CPU有一个三级缓存,在一个cpu中的不同的物理核会共享一个共同的三级缓存(Level 3 cache)
  • 每个物理核通常会运行两个逻辑核(超线程)
  • 应用程序在1个cpu内访问叫本地内存访问,切到另一个cpu上运行,需要调用原来的数据叫远端内存访问

多核CPU对redis的性能影响

当redis运行的时候,cpu进行上下文切换时,应用程序由cpu的A物理核切换到B物理核,应用程序的运行时间信息需要从L3或从内存中被重新加载到B物理核的L1、L2缓存中,就会导致redis的延迟增加。(虽然是微秒级,但是在流量高峰会出现毛刺)

多核cpu下的优化

既然这样,那我们就想办法让redis运行在一个物理核上,就可以避免因cpu切换带来的延迟问题。

Note: 绑定以后主线程、子进程、后台线程共享使用一个物理核,如果能将子进程和后台线程单独绑定物理最好(需要修改源码)

幸好linux给我们提供了一个命令 taskset

taskset命令用于设置进程(或线程)的处理器亲和性(Processor Affinity),可以将进程(或线程)绑定到特定的一个或多个CPU上去执行,而不允许将进程(或线程)调度到其他的CPU上。

bash 复制代码
#先通过lscpu查看下核的编号(一定要注意NUM架构下cpu核的编号方法)
[root@OPS-9-78 6400]# lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
Thread(s) per core: 1
Core(s) per socket: 1
座: 4
NUMA 节点: 1
厂商 ID: GenuineIntel
CPU 系列: 6
型号: 79
型号名称: Intel(R) Xeon(R) CPU E5-2630 v4 @ 2.20GHz
步进: 1
CPU MHz: 2199.998
BogoMIPS: 4399.99
超管理器厂商: VMware
虚拟化类型: 完全
L1d 缓存: 32K
L1i 缓存: 32K
L2 缓存: 256K
L3 缓存: 25600K
NUMA 节点0 CPU(s): 0-3,8-11 # NUMA架构下节点0是一个物理核,第一个逻辑核的cpu编号是0到3,第二个逻辑核的cpu编号是8-11
NUMA 节点1 CPU(s): 4-7,12-15 # NUMA架构下节点1是一个物理核,第一个逻辑核的cpu编号是4到7,第二个逻辑核的cpu编号是12-15

# 将 redis绑定到一个物理核上的两个逻辑核上,
taskset -c 0,8 ./redis-server

内存交换

swap对于操作系统来比较重要,当物理内存不足时,可以将一部分内存页进行swap操作,已解燃眉之急。swap的空间是由磁盘提供。

内存交换 (swap) 对redis来说是致命的,redis保证高性能的一个重要前提是所有的数据在内存中。如果操作系统把redis使用的部分内存换到硬盘,由于内存与磁盘的读写速度是数量级的差异,会导致发生内存交换后的redis性能急剧下降。

检查内存交换

bash 复制代码
# 查询redis的进程id
ps -ef|grep redis

# 根据进程号查询内存交换信息
cat /proc/12875/smaps |grep Swap
Swap: 0 kB
Swap: 0 kB
Swap: 4 kB
Swap: 0 kB
Swap: 0 kB

屏蔽swap

bash 复制代码
# 配置swap
echo 0 > /proc/sys/vm/swappiness
策略
0 Linux3.5 以及以上:宁愿用 OOM killer 也不用 swap
Linux3.4 以及更早:宁愿用 swap 也不用 OOM killer
1 Linux3.5 以及以上:宁愿用 swap 也不用 OOM killer
60 默认值
100 操作系统会主动地使用 swap

内存大页

linux内核从2.6.38开始支持内存大页机制。该机制支持2MB大小的内存页分配,而常规的内存页分配是按4kb来的。

为什么内存大页会影响延迟呢?这就要说到fork机制了。我们都知道fork以后,一旦数据要修改,并不会在原来的内存上修改,而是copy一份,然后再进行修改。

如果采用内存大页,即使客户端请求只修改200B的数据,redis也需要copy2MB的大页,如果是4kb的页,只会copy 4kb。这在高并发的时候就能体现出来。

bash 复制代码
# 关闭系统大页
echo never /sys/kernel/mm/transparent_hugepage/enabled

(7) 删除数据后,内存占用率无法下降

现象

删除redis数据后,用top统计时,发现redis占用了很多内存

原因

内存碎片

如何清理?

bash 复制代码
# 相关配置参数
-- 开启自动内存清理
config set activedefrag yes

-- 内存碎片的字节数达到100mb,开始清理
config set active-defrag-ignore-bytes 100mb
-- 内存碎片空间占操作系统分配给redis的总空间比例达到10%时,开始清理
config set active-defrag-threshold-lower 10

-- 表示自动清理过程所用cpu时间的比例不低于25%
active-defrag-cycle-min 25
-- 表示自动清理过程所用cpu时间的比例不高于75%,一旦超过,就停止清理,以避免影响redis
active-defrag-cycle-max 75

(8) 脑裂

Redis脑裂(Split-Brain)是指在Redis集群中发生网络分区(网络故障、网络延迟等)导致集群节点之间无法正常通信,从而导致集群分裂成多个独立的子集,每个子集都认为自己的主节点。

脑裂可能导致以下问题:

  1. 数据冲突
  2. 数据丢失
  3. 服务不可用

如何避免

在主库上设置

旧版本(3.2及以下)

复制代码
min-slaves-to-write 3
min-slaves-max-lag 10

新版本(4.0及以上)

复制代码
min-replicas-to-write 3 最少从库数量
min-replicas-max-lag 10 从库最大延迟时间

任一条件不满足,主库将不再接收请求

5. redis shake

5.1 RedisShake能做什么

redis-shake是一个用于在两个redis之间同步数据的工具,满足用户非常灵活的同步、迁移需求。

GitHub地址:https://github.com/alibaba/RedisShake

作用&应用场景

  • 数据迁移&同步
  • 版本变更
  • 架构变更
  • 容灾
  • 多活

数据迁移

支持code,支持云下到云上,云上到云上,云上到云下,其他云到阿里云等链路,灵活构建混合云场景~

Dowhat

版本升级、版本降级

Redis2.8 --> Redis 4.0

Redis4.0 --> Redis 5.0

Redis2.8 --> Redis 5.0

架构变更

单节点 主从版 集群版

m分片 --> n分片

容灾

维持超过半数的节点

机房断点,着火,地震,链路损坏...

5.2 RedisShake基本原理

(1) 功能

RedisShake的主要功能有解析、恢复、备份、同步。
功能

恢复restore:将RDB文件恢复到目的redis数据库。

备份dump:将源redis的全量数据通过RDB文件备份起来。

解析decode:对RDB文件进行读取,并以json格式解析存储

同步sync:支持源redis和目的redis的数据同步,支持全量和增量数据的迁移,以下主要介绍同步sync。

(2) 基本同步模式

redis-shake的基本原理就是模拟一个从节点加入源redis集群,首先进行全量拉取并回放,然后进行增量的拉取(通过psync命令)。

  • 支持的Redis形态
    1. Standalone:单源拉取,主从版/单节点
    2. Sentinel:从Sentinel获取地址并拉取
    3. Cluster:开源Cluster模式
    4. Proxy:从Proxy拉取
源redis节点 0. psync
1. 发送RDB
2. 发送增量命令
redis-shake 1. 写入RDB
2. 写入增量命令
目的redis节点 1. 发送RDB
2. 发送增量命令
(3) sync模式数据流图

5.3 数据同步示例

1. 下载, 解压
bash 复制代码
wget https://github.com/tair-opensource/RedisShake/releases/download/v3.1.11/redis-shake-linux-amd64.tar.gz
cd /data
tar zxvf redis-shake-linux-amd64.tar.gz -C redis-shake/
cd redis-shake/
2. 配置文件

restore.toml scan.toml sync.toml

3. 恢复
bash 复制代码
./redis-shake -conf=conf/restore.toml &
4. 数据同步
bash 复制代码
./redis-shake -conf=conf/sync.toml &

示例: 将一个单实例中的数据迁移至cluster中

步骤流程 :

创建xx.toml配置文件 --> 编写toml配置文件同步规则 --> 执行redis-shake进程 --> 核对数据同步情况

1. 创建&编写配置文件
bash 复制代码
$ cat /data/redis-shake/conf/sync-6400tocluster.toml
type = "sync"

[source]
version = 6.2 # redis version, such as 2.8, 4.0, 5.0, 6.0, 6.2, 7.0, ...
address = "127.0.0.1:6400"
username = "" # keep empty if not using ACL
password = "" # keep empty if no authentication is required
tls = false
elasticache_psync = "" # using when source is ElasticCache. ref: https://github.com/alibaba/RedisShake/issues/373

[target]
type = "cluster" # "standalone" or "cluster"
version = 6.2 # redis version, such as 2.8, 4.0, 5.0, 6.0, 6.2, 7.0, ...
# When the target is a cluster, write the address of one of the nodes.
# redis-shake will obtain other nodes through the `cluster nodes` command.
address = "127.0.0.1:6510"
username = "" # keep empty if not using ACL
password = "" # keep empty if no authentication is required

说明

  • 1.x和2.x版本过滤
    (1) 如果需要迁移全部的key,则 filter.db = 空,如下:
    filter.db =
    (2) 如果需要迁移某几个key,则分号分隔,如下:
    filter.key = aaattt;hello
    (3) 迁移:Abc.Route前缀的key、aaa前缀的key
    filter.key = Abc.Route;aaa
  • 3.x版本过滤
    使用lua脚本自定义过滤规则。Redis-shake可以用下面的命令启动:
    ./bin/redis-shake sync.toml filter/xxx.lua
2、启动
bash 复制代码
./redis-shake conf/sync-6400tocluster.toml
3、验证数据是否迁移完成
复制代码
2023-06-17 19:05:28 INF send RDB finished. address=[127.0.0.1:6400], repl-stream-db=[0]
4、新增数据验证cluster中是否存在
bash 复制代码
[root@OPS-9-78 ~]# redis-cli -p 6400 set qq 20230617
OK
[root@OPS-9-78 ~]# redis-cli -c -p 6510 get qq
"20230617"

注意

clusterA -> clusterB: 将一个clusterA (3节点) 中的数据迁移至clusterB中,需要把A集群当做3个单机实例,然后部署3个 redis-shake 进行数据同步。

5.4 redis-shake注意事项

  • 如果目标库的数据淘汰策略(maxmemory-policy)配置为noeviction以外的值,可能导致目标库的数据与源库不一致
  • 如果源库中的某些Key使用了过期(expire)机制,由于可能存在Key已过期但未被及时删除的情形,所以在目标库中查看(如通过info命令)到的Key数量会比源库的Key数量少

6、Redis备份恢复

备份

python 复制代码
def rdb_baK(self, pwd):
    cmd_baK_redis="{recmd} -h {host} -p {port} -a '{pwd}' --rdb {file}" .format(recmd=recmd, host=self.domain_ip, port=self.port, pwd=pwd, file=self.rdb_file_path)
    (status, output) = commands.getstatusoutput(cmd_baK_redis)
    log.info(output)
    if status == 0:
        log.error(output)
        return False,"backup fail"
    return True, "backup successful"

恢复

python 复制代码
def restore_rdb(self):
    #获取集群当天的rdb文件
    if not self.cmdutil.is_exists(self.rdb_dir):
        msg = "rdb_dir={} is not exist.".format(self.rdb_dir)
        self.send_mg.send_fail(tag, self.id, msg, self.title)
        return
    rdb_files_path_list = self.get_rdb_files(self.rdb_dir)
    rdb_files_path_str = rdb_files_path_list[0]
    if len(rdb_files_path_list) > 1:
        rdb_files_path_str = ";".join(rdb_files_path_list)
    log.info(rdb_files_path_str)
    #1.修改配置中的数据
    sta_m = self.modify_config(rdb_files_path_str)
    log.info(sta_m)
    if not sta_m:
        msg = "( )修改失败".format(self.shakeconf)
        self.send_mq.send_fail(tag, self.id, msg, self.title)
        return
    #2.执行恢复的命令
    cmd_shake = "../redis-shake -conf=conf/rdb_().conf -type=restore&".format(str(self.restorePort))
    log.info("cmd_shake=%s", cmd_shake)
    os.popen(cmd_shake)
    log.info("Redis data is recovering, please wait...........")
    #3.判断恢复是否完成
    sta, msg = self.is_rdb_success()
    log.info(msg)

#生成恢复用的配置文件
def modify_configelf, rdb_files_path_str):
    tar_host="{}:{}", format(self.restoreHost, str(self.restorePort))
    log.info("target.address=%s", tar_host)
    log.info("source.rdb.input=%s", rdb_files_path_str)
    target_address = "target.address = {}".format(tar_host)
    rdb_input = "source.rdb.input = {}".format(rdb_files_path_str)
    cmd_host = "sed -i 's#'target.address.*#%s#g' %s" % (target_address, self.shakeconf)
    cmd_rdb = "sed -i 's#'source.rdb.input.*#%s#g' %s" % (rdb_input, self.shakeconf)
    log.info(cmd_host)
    log.info(cmd_rdb)

    status1, output1, msg1 = self.command(cmd_host)
    if not status1:
        log.error(output1)
        return False
    status2, output2, msg2 = self.command(cmd_rdb)
    if not status2:
        log.error(output2)
        return False
    return True

7. Redis企业使用规范

开发规范

  1. key名设计

    • 建议 :可读性和可管理性
      以业务名(或数据库名)为前缀(防止key冲突),用冒号分隔,比如业务名:表名:id ugc:video:1
    • 建议 :简洁性
      保证语义的前提下,控制key的长度,当key较多时,内存占用也不容忽视,例如:
      user::{uid}:friends:messages:{mid}简化为u::{uid}:fr:m:{mid}
    • 强制 :不要包含特殊字符
      反例:包含空格、换行、单双引号以及其他转义字符
  2. value设计

    • 强制 :拒绝bigkey(防止网卡流量、慢查询) #最重要
      string类型控制在10KB以内,hash、list、set、zset元素个数不要超过5000。
      反例:一个包含200万个元素的list。
      非字符串的bigkey,不要使用del删除,使用hscan、sscan、zscan方式渐进式删除,同时要注意防止bigkey过期时间自动删除问题(例如一个200万的zset设置1小时过期,会触发del操作,造成阻塞,而且该操作不会不出现在慢查询中(latency可查),查找方法和删除方法

    • 推荐 :选择适合的数据类型。
      例如:实体类型(要合理控制和使用数据结构内存储码优化配置,例如ziplist,但也要注意节省内存和性能之间的平衡)
      反例:

      bash 复制代码
      set user::{id}:name tom
      set user::{id}:age 19
      set user::{id}:favor football

      正例:

      bash 复制代码
      hmset user::{id} name tom age 19 favor football
    • 推荐 :控制key的生命周期,redis不是垃圾桶。
      建议使用expire设置过期时间(条件允许可以打散过期时间,防止集中过期),不过期的数据重点关注idletime。

命令使用

  1. 推荐 O(N)命令关注N的数量

    例如hgetalllrangesmemberszrangesinter等并非不能使用,但是需要明确N的值。有遍历的需求可以使用hscansscanzscan代替。

  2. 推荐 :禁用命令

    禁止线上使用keysflushallflushdb等,通过redis的rename机制禁掉命令,或者使用scanf的方式渐进式处理。

  3. 推荐 合理使用select

    redis的多数据库较弱,使用数字进行区分,很多客户端支持较差,同时多业务用多数据库实际还是单线程处理,会有干扰。

  4. 推荐 使用批量操作提高效率

    原生命令:例如mgetmset

    非原生命令:可以使用pipeline提高效率。

    但要注意控制一次批量操作的元素个数(例如500以内,实际也和元素字节数有关)。

    注意两者不同:

    • 原生是原子操作,pipeline是非原子操作。
    • pipeline可以打包不同的命令,原生做不到。
    • pipeline需要客户端和服务端同时支持。
  5. 建议 Redis事务功能较弱,不建议过多使用

    Redis的事务功能较弱(不支持回滚),而且集群版本(自研和官方)要求一次事务操作的key必须在一个slot上(可以使用hashtag功能解决)

  6. 建议 Redis集群版本在使用Lua上有特殊要求:

    • 所有key都应设由 KEYS 数据来传递,redis.call/pcall 里面调用的redis命令,key的位置,必须是 KEYS array,否则直接返回error,"-ERR bad lua script for redis cluster, all the keys that the script uses should be passed using the KEYS arrayrn"
    • 所有key,必须在1个slot上,否则直接返回error,"-ERR eval/evalsha command keys must in same slotrn"
  7. 建议 必要情况下使用monitor命令时,要注意不要长时间使用。

客户端使用

  1. 推荐

    避免多个应用使用一个Redis实例

    正例:不相干的业务拆分,公共数据做服务化。

  2. 推荐

    使用带有连接池的数据库,可以有效控制连接,同时提高效率,标准使用方式:

  3. 建议

    高并发下建议客户端添加熔断功能(例如netflix hystrix)

  4. 推荐

    设置合理的密码,如有必要可以使用ssL加密访问(阿里云Redis支持)

  5. 建议

    根据自身业务类型,选好maxmemory-policy(最大内存淘汰策略),设置好过期时间。

    默认策略是volatile-lru,即超过最大内存后,在过期中使用lru算法进行key的剔除,保证不过期数据不被删除,但是可能会出现OOM问题。

    其他策略如下:

    • allkeys-lru:根据LRU算法删除键,不管数据有没有设置超时属性,直到腾出足够空间为止。
    • allkeys-random:随机删除所有键,直到腾出足够空间为止。
    • volatile-random:随机删除过期键,直到腾出足够空间为止。
    • volatile-ttl:根据键值对象的ttl属性,删除最近将要过期数据。如果没有,回退到noeviction策略。
    • noeviction:不会删除任何数据,拒绝所有写入操作并返回客户端错误信息"(error) OOM command not allowed when used memory",此时Redis只响应读操作。

删除bigkey

redis 4.0已经支持key的异步删除,欢迎使用。

  1. Hash删除:hscan + hdel
  2. List删除:ltrim
  3. Set删除:sscan + srem
  4. SortedSet删除:zscan + zrem

8. cachedoud

(1) CacheCloud 是什么?

CacheCloud是一个Redis云管理平台,支持Redis多种架构(Standalone、Sentinel、Cluster)高效管理、有效降低大规模redis运维成本,提升资源管控能力和利用率。平台提供快速搭建/迁移,运维管理,弹性伸缩,统计监控,客户端整合接入等功能。

(2) 部署

获取运行war包

CacheCloud 支持两种部署方式

  • 源码编译 后运行
  • 直接下载war包运行

初始化数据库

创建一个cachecloud的数据库

执行项目中sql目录下对应版本的sql文件,我部署的是3.2,执行的3.2.sql。

修改配置文件

在项目的src/main/resources目录下,有几个配置文件

  • application-local.yml
  • application-online.yml
  • application-open.yml
  • application-test.yml

这几个配置文件为不同环境的配置。我使用的local环境,就配置了application-local.yml

主要配置是mysql和redis的配置

yaml 复制代码
cachecloud:
 primary:
   url: jdbc:mysql://xxxx:3306/cachecloud_open?useUnicode=true&characterEncoding=UTF8&autoReconnect=true&connectTimeout=3000&socketTimeout=10000&serverTimezone=Asia/Shanghai
   user: root
   password: xxxxxx
   initialPoolSize: 1
   maxPoolSize: 3
 redis: #配置cachecloud-web需要的redis,用户存储任务流log
   main:
     host: xxxx
     port: 6379
     password: 123456

启动项目

bash 复制代码
#启动web工程,通过-Dspring.profiles.active=local 指定启动环境
nohup java -jar cachecloud-web.war -Dspring.profiles.active=local &

项目启动后直接ip:端口访问,我的ip是192.168.9.78,账户名和密码是admin、admin

http://192.168.9.78:8080/manage/login

(3) 配置修改

CacheCloud管理界面功能

  • 全局统计
  • client统计
  • server统计
  • 工单审批
  • 应用运维
  • 实例运维
  • 应用导入
  • 数据迁移
  • 诊断工具
  • 机器管理
  • 报警配置
  • 系统配置
  • 资源管理

配置修改

填写配置

复制代码
ssh授权方式(*): 密码
机器ssh用户名(*): root
机器ssh密码(*): 111111
公钥用户名(*): cachecloud-open
密钥路径(*): /opt/ssh/id_rsa
机器ssh端口(*): 22
cachecloud-admin用户名(*): admin
cachecloud-admin密码(*): admin

(4) 添加机器

机器管理界面

复制代码
机器ID: 机器ID:多台机器分隔 注:多台机器用:分隔
机器: 默认机器
内存: 机器内存(单位G) G
CPU: 机器CPU接收 核
disk: 机器磁盘空间G G
是否虚拟: 否
操作系统: centos
主机ID: 宿主机ID: 多台机器分隔 注:多台机器用:分隔
机器信息: Redis机器(默认) 机器类型:

(5) 导入应用

导入应用主要的是把分散在各个地方的redis导入到cacheCloud平台,注意,不是接管,而是在cacheCloud中创建一个新的redis应用服务,将原来的数据迁移过来。

应用导入流程

  1. 确认导入配置
  2. 创建Redis版本
  3. 新建应用
  4. 数据迁移
  5. 应用导入完成

导入前准备:

  • 为应用创建版本
  • 部署应用
  • 新老实例redis数据迁移
  • 导入完成

应用创建状态:

    1. 应用部署异常,请【修复】或【重新部署】

从【获得申请】->【导入应用】填写相关申请信息

应用导入申请

复制代码
源:Redis实例信息
存储类型: Redis-standalone
实例详情(*): 192.168.1.150:6379
redis密码: 123456
redis密码,如果没有则为空

实例格式说明
每行格式都是: ip:port(例如:10.10.xx.xx:6379)
1. standalone类型:
    master:ip:masterPort
2. sentinel类型:
    master_name:master
    sentinel:ip1:sentinelPort1
    sentinel:ip2:sentinelPort2
    sentinel:ip3:sentinelPort3
3. cluster类型:
    master:ip1:masterPort1
    master:ip2:masterPort2
    master:ip3:masterPort3

目标:应用信息

复制代码
应用名称(*): show-home-local
如:cachecloud-js-online,全局唯一
应用描述(*): 演示信息
不超过128个字符,可以包含中文
项目负责人(*): 琳达【linda@qq.com】
存储种类: Redis-standalone ✔ 内存总量(*): 1
Redis部署版本: redis-5.0.9 ✔ 其他: 格式:redis-x.x.x
测试: 否 ✔ 是否有数据备份: 是 ✔
是否需要持久化: 是 ✔ 是否需要slave: 是 ✔
预估QPS(*): 800 预估条目数量:(*): 100000
客户端机房:(*): local (192.168.1.*)
内存报警阀值(*): 90
例如:内存使用率超过90%报警,请填写90(大于100以上则不报警)
客户端连接数报警阀值(*): 2000
例如:如客户端连接数超过2000报警,填写2000
检查格式 提交申请

申请完以后,在我的工单里出现一条导入任务

管理员审批完以后,就会部署迁移了,对是迁移,创建一个新的节点迁移进来

应用部署信息示例

复制代码
应用部署 ID:1

| 应用Id    | 1    | 应用名称    | show-home-local |
|-----------|------|-------------|-----------------|
| 存储种类    | RedisStandalone | 内存申请详情    |                 |
| 是否需要路由器 | 是    | 是否有后续数据源 | 有              |
| 是否测试    | 否    | 是否需要持久化  | 是              |
| 预估QPS    | 800  | 预估条目数量   | 100000          |
| 客户端机房信息 | local | Redis版本   | redis-5.0.9     |
| 申请安装Redis模块 |      | 淘汰策略     |                 |

应用基础信息
| 应用级别    | B    | ✔           |
|-------------|------|-------------|
| Redis版本   | redis-5.0.9 | ✔           |
| Redis密码: | 2651080c6814a449d62da69a12f962b6 | □设置自定义密码 |

Redis模块信息申请安装模块
选择安装Redis模块:

应用部署信息
| 应用类型*: | Redis-Standalont | maxMemory*: | 512 |
相关推荐
r***12381 小时前
GO 快速升级Go版本
开发语言·redis·golang
一顿操作猛如虎,啥也不是!1 小时前
redis注册成windows服务,开机启动
数据库·redis·缓存
黎明晓月1 小时前
Redis容器化(Docker)
java·redis·docker
Knight_AL2 小时前
MongoDB、Redis、MySQL 如何选型?从真实业务场景谈起
redis·mysql·mongodb
凹凸曼说我是怪兽y4 小时前
Redis分布式锁详细实现演进与Redisson深度解析
数据库·redis·分布式
@淡 定10 小时前
Redis热点Key独立集群实现方案
数据库·redis·缓存
吳所畏惧11 小时前
Linux环境/麒麟V10SP3下离线安装Redis、修改默认密码并设置Redis开机自启动
linux·运维·服务器·redis·中间件·架构·ssh
困知勉行198514 小时前
springboot整合redis
java·spring boot·redis
飞鸟真人14 小时前
Redis面试常见问题详解
数据库·redis·面试