Redis中的配置与优化过程
作者:ikun·
一、 Redis 介绍
1. 关系型数据库与非关系型数据库
数据库按照数据库的结构可以分为关系型数据库与其他数据库,而这些其他数据库我们将其统称为非关系型数据库。
(1) 关系型数据库
关系型数据库是一个结构化的数据库,创建在关系模型基础上,一般面向于记录。它借助于集合代数等数学概念和方法来处理数据库中的数据。关系模型就是指二维表格模型,因而一个关系型数据库就是由二维表及其之间的联系组成的一个数据组织。现实世界中,各种实体与实体之间的各种联系都可以用关系模型来表示。SQL 语句(标准数据查询语言)就是一种基于关系型数据库的语言,用于执行对关系型数据库中数据的检索和操作。
(2) 非关系型数据库
NoSQL(NoSQL = Not 0nly SQL),意思是“不仅仅是 SQL”,是非关系型数据库的总称。主流的 NoSQL 数据库有 Redis、MongBD、Hbase、CouhDB 等等。以上这些非关系型数据库,他们的存储方式、存储结构以及使用的场景都是完全不同的。所以我们认为它是一个非关系型数据库的集合,而不是像关系型数据库一样,是一个统称。换言之,除了主流的关系型数据库以外的数据库,都可以认为是非关系型的。NoSQL 数据库凭借着其非关系型、分布式、开源及横向扩展等优势,被认为是下一代数据库产品。
2. Redis 基础
2.1 Redis 简介
Redis (RemoteDictionaryServer,远程字典型)是一个开源的、使用C语言编写的 NoSQL 数据库。Redis 基于内存运行并支持持久化,采用 key-value(键值对)的存储形式,是目前分布式架构中不可或缺的一环。
Redis 服务器程序是单进程模型,也就是再一台服务器上可以同时启动多个 Redis 进程,而 Redis 的时间处理速度则是完全依靠与主进程的执行效率。若再服务器上只运行一个 Redis 进程,当多个客户端访问的时,服务器的处理能力是会有一定程度的下降;若再同一太服务器上开启多个 Redis 进程,Redis 在提高并发处理能力的同时会给服务器的 CPU 造成很大压力。即:在实际生产环境中,需要根据实际的需求来决定开启多少个Redis 进程。若对高并发要求更高一些,可能会考虑在同一台服务器上开启多个进程。若 CPU 资源比较紧张,采用单进程即可。
Redis 具有以下几个优点:
- 具有极高的数据读写速度,数据读取的速度最高可达到 110000 次/s,数据写入速度最高可达到 81000 次/s。
- 支持丰富的数据类型,不仅仅支持简单的 key-value 类型的数据,还支持Strings,Lists,Hashes,Sets 及 0rdered Sets 等数据类型操作。
- 支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
- 原子性,Redis 所有操作都是原子性的
- 支持数据备份,即 master-salve 模式的数据备份。
Redis 作为基于内存运行的数据库,缓存是其最常应用的场景之一。除此之外,Redis常见应用场景还包括获取最新 N个数据的操作、排行榜类应用、计数器应用、存储关系、实时分析系统、日志记录。
2.2 安装部署
Redis 的安装相对于其他服务来说比较简单 。首先需要到 Redis 官网(https://www.redis.io)下载相应的源码软件包,然后上传至 Linux 系统的服务器中进行解压、安装。本文以 redis-4.0.9.tar.gz 为例进行 Redis 服务的安装和配置。
通常情况下,在 Linux 系统中进行源码编译安装,需要先执行./configure进行环境检查与配置,从而生成 Makefile 文件,再执行 make && make install命令进行编译安装。而 Redis 源码包中直接提供了 Makefile 文件,所以在解压完软件包后,可直接进入解压后的软件包目录,执行make与 make insta11命令进行安装。
dnf -y install tar gcc zlib-devel tar xvzf redis-4.0.9. tar.gz tar xvzf redis-4.0.9. tar.gz cd redis-4.0.9/ make && make PREFIX=/usr/local/redis install ln-s /usr/local/redis/bin/* /usr/local/bin/
make insta11 只是安装了二进制文件到系统中,并没有启动脚本和配置文件。
软件包中默认提供了一个 install server.sh 脚本文件,通过该脚本文件可以设置 Redis 服务所需要的相关配置文件。
当脚本运行完毕,Redis 服务就已经启动,默认侦听端口为 6379。
cd utils/ ./install server.sh /etc/init.d/redis 6379 start
2.3 配置参数
Redis 主配置文件为/etc/redis/6379.conf,由注释行与设置行两部分组成。与大多数 Linux 配置文件一样,注释性的文字以“#”开始,包含了对相关配置内容进行的说明和解释。
除了注释行与空行以外的内容即为设置行。
可根据生产环境的需求调整相关参数,如下:
vim /etc/redis/6379.conf bind 127.0.0.1 192.168.10.161 //监听的主机地址 port 6379 //端日 daemonize yes //启用守护进程 pidfile /var/run/redis 6379.pid //指定 PID 文件 loglevel notice //日志级别 logfile /var/log/redis 6379.1og //指定日志文件
3. Redis 命令工具
Redis 软件提供了多个命令工具。安装 Redis 服务时,所包含的软件工具会同时被安装到系统中,在系统中可以直接使用。
这些命令工具的作用分别如下所示:
- redis-server:用于启动 Redis 的工具
- redis-benchmark:用于检测 Redis 在本机的运行效率
- redis-check-aof:修复 AOF 持久化文件
- redis-check-rdb:修复 RDB 持久化文件
- redis-cli:Redis 命令行工具
3.1 redis-cli 命令行工具
Redis 数据库系统也是一个典型的 C/S(客户端/服务器端)架构的应用,要访问 Redis 数据库需要使用专门的客户端软件。
Redis 服务的客户端软件就是其自带的 redis-cli 命令行工具。
使用 redis-cli 连接指定数据库,连接成功后会进入提示符为“远程主机 IP 地址:端口号>”的数据库操作环境.
3.2 redis-benchmark 测试工具
redis-benchmark 是官方自带的 Redis 性能测试工具,可以有效的测试Redis 服务的性能。
基本的测试语法为 redis-benchmark[option] [optionvalue]。
常用选项如下所示:
- -h:指定服务器主机名
- P:指定服务器端口
- -s:指定服务器 socket
- -c:指定并发连接数
- -n:指定请求数
- -d:以字节的形式指定 SET/GET 值的数据大小
- -k:1=keep alive =reconnect
- -r:SET/GET/INCR 使用随机 key,SADD 使用随机值
- -p:通过管道传输<numreg>请求
- -q:强制退出 redis。仅显示 query/sec 值
- --csv:以CSV 格式输出
- -l:生成循环,永久执行测试
- -t:仅运行以逗号分隔的测试命令列表
- -I:Idle 模式。仅打开 N个idle 连接并等待
4. redis 数据库常用命令
前面提到 Redis 数据库采用 key-value(键值对)的数据存储形式。
所使用的命令是 set与 get 命令。
- set:存放数据,基本的命令格式为 set key value。
- get:获取数据,基本的命令格式为 get key。
4.1 key 相关命令
在 Redis 数据库中,与 key 相关的命令主要包含以下几种。
(1) keys
用于查找和模式匹配的键
KEYS * # 查看所有键 KEYS user:* # 查看以user:开头的键
(2) exists
检查键是否存在
SET name "Alice" # 设置键值 EXISTS name # 返回1(存在) EXISTS age # 返回0(不存在)
(3) del
删除一个或多个键
SET a 1 SET b 2 # 设置两个键 DEL a b # 删除两个键,返回2(成功删除的数量)
(4) type
获取键的数据类型
SET num 100 # 设置字符串 TYPE num # 返回string LPUSH list 1 2 # 创建列表 TYPE list # 返回list
(5) rename
重命名键
SET msg "hello" # 设置键值 RENAME msg greeting # 重命名键 GET greeting # 返回"hello"
(6) renamenX
仅在新键不存在时重命名
SET old "value" # 设置旧键 SET new "other" # 设置新键 RENAMENX old new # 返回0(新键已存在) DEL new # 删除新键 RENAMENX old new # 返回1(重命名成功)
(7) dbsize
查看当前数据库的键总数
DBSIZE # 返回当前数据库的键数量
二、 Redis 持久化
1. RDB 和 AOF 的区别
维度 | RDB(快照持久化) | AOF(日志持久化) |
持久化方式 | 定时生成数据库快照文件(.rdb),保存某一时刻的全量数据。 | 记录所有写操作命令日志,以追加方式写入文件(.aof)。 |
数据安全性 | 可能丢失最后一次快照到故障期间的数据(取决于快照间隔)。 | 可配置每秒同步(最多丢失 1 秒数据)或实时同步,数据更安全。 |
文件大小 | 快照文件紧凑,占用空间小。 | 日志文件可能较大(需定期重写)。 |
恢复速度 | 加载快照速度快,适合大规模数据恢复。 | 重放日志速度较慢,尤其是日志文件很大时。 |
对性能影响 | 快照生成时可能有短暂阻塞(Fork 子进程)。 | 持续写入日志对性能影响较小(取决于同步策略)。 |
2. RDB 和 AOF 的优缺点
2.1 RDB 优缺点
优点:
- 文件体积小:适合备份和远程传输,占用磁盘空间少。
- 恢复速度快:直接加载二进制快照,比重放日志更快。
- 对主进程影响小:快照生成由子进程完成,主进程无需阻塞(除 Fork 瞬间)。
缺点:
- 数据丢失风险:若快照间隔较长(如 5 分钟),故障时可能丢失大量数据。
- 生成快照时阻塞:Fork 子进程时可能阻塞主进程(取决于数据量)。
2.2 AOF 优缺点
优点:
- 数据安全性高:可配置
appendfsync always
实时同步,几乎不丢数据。 - 日志可读性强:AOF 文件本质是命令日志,可手动解析或修改(需谨慎)。
- 增量写入:持续追加日志,无磁盘随机写操作,更适合机械硬盘。
缺点:
- 文件膨胀问题:长期写入会导致 AOF 文件过大,需定期重写。
- 恢复速度慢:重放所有日志命令,数据量大时恢复耗时较长。
- 性能开销:
appendfsync always
会降低写入性能(每次写操作都同步磁盘)。
3. Redis 持久化配置
3.1 RDB 持久化配置
RDB 配置在redis.conf
中,核心参数:
# 快照触发条件:900秒内至少1个键变更,或300秒内至少10个键变更,或60秒内至少10000个键变更 save 900 1 save 300 10 save 60 10000 # 禁用RDB(注释掉所有save配置) # save "" # RDB文件名和存储目录 dbfilename dump.rdb dir /var/lib/redis/
3.2 AOF 持久化配置
开启 AOF 并配置同步策略:
# 启用AOF appendonly yes # AOF同步策略: # always:每次写操作都同步磁盘(性能最低,数据最安全) # everysec:每秒同步一次(默认,推荐) # no:由操作系统决定(性能最高,数据可能丢失最多) appendfsync everysec # 当AOF文件大小超过上次重写后体积的100%时触发自动重写 auto-aof-rewrite-percentage 100 # 当AOF文件至少达到64MB时才触发自动重写 auto-aof-rewrite-min-size 64mb
4. AOF 重写
- 作用:压缩 AOF 文件,移除冗余命令(如多次修改同一键的历史操作)。
- 触发方式:手动触发:
BGREWRITEAOF
命令。自动触发:满足auto-aof-rewrite-percentage
和auto-aof-rewrite-min-size
配置。 - 原理:Redis 通过子进程遍历当前数据库,生成新的 AOF 日志(仅包含最终数据状态的命令),并替换旧文件,过程中不阻塞主进程(基于 Copy-On-Write 机制)。
三、 性能管理
1. 内存碎片化
- 原因:Redis 使用内存分配器(如 jemalloc)管理内存,分配和释放小对象时可能产生碎片。
- 查看方式:通过
INFO memory
命令查看mem_fragmentation_ratio
(理想值 1.0~1.5)。 - 解决方法:重启 Redis(重建内存布局)。调整分配器参数(如 jemalloc 的
malloc_profile
)或更换分配器(如 tcmalloc)。
2. 内存使用率
2.1 针对缓存数据大小选择
- 避免存储过大的 value(如大字符串),可拆分为多个小 key 或使用压缩(如
COMPRESS
命令)。 - 示例:存储 100 万用户信息时,用
Hash
结构(HSET user:1 name "Alice"
)比 100 万个字符串键更省空间。
2.2 使用 Hash 数据结构
当数据包含多个字段时,用Hash
代替多个独立字符串键:
# 推荐方式(节省内存) HSET user:1 name "Alice" age 25 city "Beijing" # 不推荐方式(每个字段一个键) SET user:1:name "Alice" SET user:1:age "25" SET user:1:city "Beijing"
2.3 设置 key 的过期时间
- 对临时数据设置过期时间(
EXPIRE key seconds
),避免无用数据长期占用内存。
3. 回收 key
过期策略:
- 惰性删除:获取 key 时检查是否过期,过期则删除。
- 定期删除:Redis 定期随机检查部分 key,删除过期键。
内存淘汰策略(当内存不足时):
volatile-lru
:从设置过期时间的键中删除最久未使用的。allkeys-lru
:从所有键中删除最久未使用的(推荐常用场景)。volatile-random
:随机删除设置过期时间的键。noeviction
:拒绝写入操作(默认策略,需手动配置为其他策略)。
配置方式:
- 在
redis.conf
中设置maxmemory-policy allkeys-lru
。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。