目录
一:Redis介绍
1:关系数据库与非关系数据库
1.1:关系数据库
定义:
关系数据库(Relational Database)是基于关系模型(Relational Model)的数据库,使用表格(表、行、列)的结构存储和管理数据。数据之间通过主键(Primary Key)和外键(Foreign Key)建立关联。
特点:
结构化数据: 数据以严格的二维表形式存储,遵循预定义的模式(Schema)。
SQL操作: 使用结构化查询语言(SQL)进行数据操作和查询。
ACID特性: 支持事务的原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability),适合需要高一致性的场景。
规范化设计: 通过范式(Normalization)减少数据冗余,提高数据完整性。
1.2:非关系数据库
定义:
非关系数据库(NoSQL, Not Only SQL)是一类不依赖传统关系模型的数据库,设计灵活,适合处理大规模、非结构化或半结构化数据。
特点:
灵活的数据模型:
支持键值对(Key-Value)、文档(Document)、列族(Column Family)、图(Graph)等数据模型。
无固定模式(Schema-less),可动态扩展字段。
高扩展性: 通常支持分布式架构,易于水平扩展(如分片、副本集)。
高性能: 针对特定场景优化(如高吞吐、低延迟)。
弱化ACID: 部分NoSQL数据库牺牲严格的一致性,追求高可用性和分区容错性(遵循CAP定理)。
1.3:非关系数据库背景
(1)High performance—— 对数据库高并发读写需求
Web2.0 网站会根据用户的个性化信息来实时生成动态页面和提供动态信息,因此无法使用动态页面静态化技术。所以数据库的并发负载非常高,一般会达到 10000 次 /s 以上的读写请求。关系型数据库对于上万次的查询请求还是可以勉强支撑的,但出现上万次的写数据请求,硬盘 IO 就已经无法承受了。对于普通的 BBS 网站,往往也会存在高并发的写数据请求。
(2)Huge Storage—— 对海量数据高存储与访问需求
类似于 Facebook、Friendfeed 这样的 SNS 网站,每天会产生大量的用户动态信息。如 Friendfeed,一个月就会产生不少于 2.5 亿条用户动态信息,对于关系型数据库来说,在一个包含 2.5 亿条记录的表中执行 SQL 查询,查询效率是非常低的。
(3)High Scalability && High Availability—— 对数据库高可扩展性与高可用
用户需求在 Web 架构中,数据库是最难进行横向扩展的。当应用系统的用户量与访问量与日俱增时,数据库是没办法像 Web 服务一样,简单地通过添加硬件和服务器节点来扩展其性能和负载能力的。尤其对于一些需要 24 小时对外提供服务的网站来说,数据库的升级与扩展往往伴随着停机维护与数据迁移,其工作量是非常庞大的。
2:Redis基础
2.1:Redis简介
Redis(RemoteDictionaryServer,远程字典典型)是一个开源的、使用 C 语言编写的 NoSQL 数据库。Redis 基于内存运行并支持持久化,采用 key - value(键值对)的存储形式,是目前分布式架构中不可或缺的一环。
Redis 服务器程序是单进程模型,也就是在一台服务器上可以同时启动多个 Redis 进程,而 Redis 的实际处理速度则是完全依靠于主进程的执行效率。
Redis具有以下几个优点:
- 具有极高的数据读写速度,数据读取的速度最高可达到 110000 次 /s,数据写入速度最高可达到 81000 次 /s。
- 支持丰富的数据类型,不仅仅支持简单的 key - value 类型的数据,还支持 Strings,Lists,Hashes,Sets 及 Ordered Sets 等数据类型操作。
- 支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
- 原子性,Redis 所有操作都是原子性的。
- 支持数据备份,即 master - salve 模式的数据备份。
2.2:Redis安装部署
#上传安装包redis-4.0.9.tar.gz
#关闭防火墙
systemctl stop firewalld
setenforce 0
#部署环境
dnf -y install gcc zlib-devel
#解压安装包redis-4.0.9.tar.gz
tar zxvf redis-4.0.9.tar.gz
cd redis-4.0.9/
#编译安装
make
#定义安装路径
make PREFIX=/usr/local/redis install
cd /usr/local/redis
#做软链接
ln -s /usr/local/redis/bin/* /usr/local/bin/
#做初始化
cd redis-4.0.9/
cd utils/
./install_server.sh(可以直接默认)
##需要手动输入
Selected config:
Port : 6379
Config file : /etc/redis/6379.conf //配置文件路径
Log file : /var/log/redis_6379.log //日志文件路径
Data dir : /var/lib/redis/6379 //数据文件路径
Executable : /usr/local/redis/bin/redis-server //可执行文件 路径
Cli Executable : /usr/local/redis/bin/redis-cli //客户端命令行工 具
#检查开启状态
netstat -anpt | grep redis
#关于redis服务的命令
/etc/init.d/redis_6379 stop #关闭redis服务
/etc/init.d/redis_6379 start #启动redis服务
/etc/init.d/redis_6379 restart #启动redis服务
/etc/init.d/redis_6379 status #查看redis服务
2.3:配置参数
#配置参数
vim /etc/redis/6379.conf
bind 127.0.0.1 192.168.10.201
/etc/init.d/redis_6379 restart #启动redis服务
参数 | 作用 |
---|---|
timeout 300 | 当客户端闲置多长时间后关闭连接,如果指定为 0,表示关闭该功能 |
dbfilename dump.rdb | 指定本地数据库文件名,默认值为 dump.rdb |
dir /var/lib/redis/6379 | 指定本地数据库存放目录 |
maxclients 10000 | 设置同一时间最大客户端连接数,默认为 10000。Redis 可以同时打开的客户端连接数为 Redis 进程可以打开的最大文件描述符数,如果设置 maxclients 0,表示不限制。当客户端连接数到达限制时,Redis 会关闭新的连接并向客户端返回 max number of clients reached 错误信息 |
rdbcompression yes | 指定存储至本地数据库时是否压缩数据,默认为 yes。Redis 采用 LZF 压缩,如果为了节省 CPU 资源,可以关闭该选项,但会导致数据库文件变的巨大 |
slaveof <masterip><masterport> | 当本机为从服务器时,设置主服务的 IP 地址及端口。在 Redis 启动时,从服务器会自动从主服务进行数据同步 |
masterauth <master-password> | 当主服务设置了密码保护时,从服务连接主服务的密码 |
requirepass foobared | 设置 Redis 连接密码,如果配置了连接密码,客户端在连接 Redis 时需要通过 AUTH <password>命令提供密码,默认关闭 |
maxmemory <bytes> | 指定 Redis 最大内存限制。Redis 在启动时会把数据加载到内存中,达到最大内存后,Redis 会先尝试清除已到期或即将到期的 Key,当此方法处理后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis 新 VM 机制,会把 Key 存放内存,Value 会存放在 Swap 分区 |
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 地址:端口号” 的数据库操作环境,例如 “127.0.0.1:6379>” 。用户可以输入各种操作语句对数据库进行管理。如执行 ping 命令可以检测 Redis 服务是否启动。
redis-cli
127.0.0.1:6379>ping //检测redis服务是否启动
PONG(pingpong机制)
#远程连接
redis-cli -h 192.168.10.201 -p 6379
127.0.0.1:6379>help //帮助输入指令
3.2:redis-benchmark测试工具
redis - benchmark 是官方自带的 Redis 性能测试工具,可以有效的测试 Redis 服务的性能。基本的测试语法为 redis - benchmark [option] [option value]。常用选项如下所示。
- h:指定服务器主机名;
- p:指定服务器端口;
- s:指定服务器 socket;
- c:指定并发连接数;
- n:指定请求数;
- d:以字节的形式指定 SET/GET 值的数据大小;
- k:1=keep ALIVE 0=reconnect;
- r:SET/GET/INCR 使用随机 key,SADD 使用随机值;
- P:通过管道传输<numreq>请求;
- q:强制退出 redis。仅显示 query/sec 值;
- --csv:以 CSV 格式输出;
- l:生成循环,永久执行测试;
- t:仅运行以逗号分隔的测试命令列表;
- I:Idle 模式。仅打开 N 个 idle 连接并等待。
redis-benchmark -h 192.168.10.201 -p 6379 -c 100 -n 10000
//与redis建立100个并发连接,与10000个请求测试性能(10*10000)
redis-benchmark -h 192.168.10.201 -p 6379 -q -d 100
//让redis以字节的方式设置键值
redis-benchmark -t set,lpush -n 10000 -q
//redis服务进行set,lpush的操作
4:Redis数据库常用的命令
前面提到 Redis 数据库采用 key-value(键值对)的数据存储形式。所使用的命令是 set
与 get 命令。
- set:存放数据,基本的命令格式为 set key value。
- get:获取数据,基本的命令格式为 get key。
例如,在 Redis 的命令行模式下执行”set teacher zhanglong”,表示在当前数据库下存放一个 key 为 teacher,value 为 zhanglong 的数据,而执行 “getteacher” 命令即可查看刚才存放的数据。
127.0.0.1:6379>set teacher zhangsan
//存放数据,键为teacher,值为zhangsan,在teacher下放入zhangsan
127.0.0.1:6379>get teacher
//获取数据
4.1:key相关命令
(1)keys
127.0.0.1:6379>set teacher zhangsan
//存放数据,键为teacher,值为zhangsan,在teacher下放入zhangsan
127.0.0.1:6379>keys *
//查看当前数据库中的所有键
127.0.0.1:6379>keys v*
//查看当前数据库中以v开头所有键
127.0.0.1:6379>keys v?
//查看当前数据库中以v开头后面包含任意一位数据
127.0.0.1:6379>keys v??
//查看当前数据库中以v开头后面包含任意两位数据
(2)exists
exists命令可以判断键值是否存在
127.0.0.1:6379>exists teacher
//判断teacher键是否存在
(integer)1 //表示teacher键存在
(integer)0 //表示teacher键不存在
(3)del
del命令可以删除当前数据库的指定key
127.0.0.1:6379>keys *
//查看当前数据库中的所有键
127.0.0.1:6379>del v5
//随机删一个
(4)type
使用type命令可以获取key对应的值类型
127.0.0.1:6379>type k1
(5)rename
rename命令的作用对已有key进行重命名
命令格式为:rename 源 key 目标 key
127.0.0.1:6379>rename name旧名 name新名
(无论目标 key 是否存在都进行重命名,且源 key 的值会覆盖目标 key 的值)
(6)renamenx
(renamenx k1 k2 把k1重命名为k2,如果k2 已存在,就停止命名)
renamenx命令的作用对已有key进行重命名,并检测新名是否存在。
127.0.0.1:6379>keys *
//查看当前数据库中的所有键
127.0.0.1:6379>get teacher
//获取数据
127.0.0.1:6379>renamenx name旧名 name新名
(7)dbsize
查看当前数据库中 key 的数目
127.0.0.1:6379>dbsize
4.2:多数据库常用命令
(1)多数据库切换
Redis 支持多数据库,Redis 在没有任何改动的情况下默认包含 16 个数据库,数据库名称是用数字 0 - 15 来依次命名的。使用 select 命令可以进行 Redis 的多数据库之间的切换,命令格式为 selectindex,其中 index 表示数据库的序号。而使用 redis - cli 连接 Redis 数据库后,默认使用的是序号为 0 的数据库。
127.0.0.1:6379>select 10 // 切换至序号为 10 的数据库
OK
127.0.0.1:6379 [10]>select 15 // 切换至序号为 15 的数据库
OK
127.0.0.1:6379 [15]>select 0 // 切换至序号为 0 的数据库
OK
127.0.0.1:6379>
(2)多数据库间移动数据
Redis 的多数据库在一定程度上是相对独立的,例如在数据库 0 上面存放 k1 的数据,在其它 1 - 15 的数据库上是无法查看到的。
127.0.0.1:6379>set k1 100
OK
127.0.0.1:6379>get k1
"100"
127.0.0.1:6379>select 1
OK
127.0.0.1:6379 [1]>get k1
(nil)
(3)清除数据库内数据
Redis 数据库的整库数据删除主要分为两个部分:清空当前数据库数据,使用 FLUSHDB 命令实现;清空所有数据库的数据,使用 FLUSHALL 命令实现。但是,数据清空操作比较危险,生产环境下一般不建议使用。
二:Redis持久化
1:RDB和AOF的区别
特性 | RDB (Redis Database) | AOF (Append Only File) |
---|---|---|
持久化方式 | 生成数据快照 | 记录所有写操作命令 |
文件格式 | 二进制压缩文件 | 文本协议格式(可读) |
恢复速度 | 快(直接加载数据) | 慢(需重放所有命令) |
数据安全性 | 可能丢失最后一次快照后的数据 | 根据配置可做到几乎不丢失数据 |
体积 | 较小(压缩存储) | 较大(持续增长,需重写优化) |
性能影响 | 写时复制可能短暂阻塞主线程 | 文件同步策略影响写入性能 |
2:RDB和AOF的优缺点
2.1:RDB优缺点
优点:
恢复速度快,适合大规模数据恢复
文件紧凑,节省磁盘空间
适合备份(可定时生成快照)
最大化Redis性能(父进程无需额外IO)
缺点:
可能丢失最后一次快照后的数据(不够实时)
大数据量时fork过程可能阻塞服务(GB级数据)
频繁持久化影响性能
2.2:AOF优缺点
优点:
数据更安全(支持秒级持久化)
文件易读可修改(文本格式)
自动重写机制优化文件体积
支持多种同步策略(如每秒同步)
缺点:
文件体积通常大于RDB
恢复速度较慢(需重放命令)
高频写入时性能影响较大
历史版本兼容性问题(重写时)
3:Redis持久化配置
3.1:RDB持久化配置
# 触发保存条件(格式:save <seconds> <changes>)
save 900 1 # 900秒内至少1个key变化
save 300 10 # 300秒内至少10个key变化
save 60 10000 # 60秒内至少10000个key变化
stop-writes-on-bgsave-error yes # 持久化失败时停止写入
rdbcompression yes # 启用压缩
rdbchecksum yes # 启用校验和
dbfilename dump.rdb # 文件名
dir ./ # 存储目录
3.2:AOF持久化配置
appendonly yes # 启用AOF
appendfilename "appendonly.aof" # 文件名
# 同步策略(三选一)
# appendfsync always # 每个命令都同步(最安全但最慢)
appendfsync everysec # 每秒同步(推荐)
# appendfsync no # 由操作系统决定
auto-aof-rewrite-percentage 100 # 文件增长比例阈值
auto-aof-rewrite-min-size 64mb # 最小重写文件大小
aof-load-truncated yes # 加载截断的AOF文件
aof-use-rdb-preamble yes # 混合持久化(Redis 4+)
4:AOF重写
Redis 会不断地将被执行的命令记录到 AOF 文件里面,所以随着 Redis 不断运行,AOF 文件的体积也会不断增长。在极端情况下,体积不断增大的 AOF 文件甚至可能会用完硬盘的所有可用空间。Redis 在重启之后需要通过重新执行 AOF 文件记录的所有命令来还原数据集,所以如果 AOF 文件的体积非常大,那么还原操作执行的时间就可能会非常长。
为了解决 AOF 文件体积不断增大的问题,用户可以向 Redis 发送 BGREWRITEAOF 命令。BGREWRITEAOF 命令会通过移除 AOF 文件中的冗余命令来重写(rewrite)AOF 文件,使 AOF 文件的体积尽可能地变小。
三:性能管理
Redis 性能管理需要关注的数据指标有内存使用率、内存碎片率、回收 key 等。这其中有些数据可以通过进入 info 命令进行查看。需要查看某一项的值就后面跟具体参数,执行以下命令查看 Redis 使用内存值。
192.168.9.236:7001> info memory
Memory
used_memory:1789108864
used_memory_human:1.67G
used_memory_rss:1834389504
used_memory_rss_human:1.71G
used_memory_peak:4657473880
used_memory_peak_human:4.34G
used_memory_peak_perc:38.41%
used_memory_overhead:6268599900
used_memory_startup:791432
used_memory_dataset:1162248964
used_memory_dataset_perc:64.99%
allocator_allocated:1789471472
allocator_active:1804185600
allocator_resident:1853542400
total_system_memory:100953268224
total_system_memory_human:94.02G
used_memory_lua:37888
used_memory_lua_human:37.00K
1:内存碎片率
- 内存碎片率超过 1.5
重启 Redis 服务器可以让额外产生的内存碎片失效并重新作为新内存来使用,使操作系统恢复高效的内存管理。额外碎片的产生是由于 Redis 释放了内存块,但内存分配器并没有返回内存给操作系统,这个内存分配器是在编译时指定的,可以是 libc、jemalloc 或者 tcmalloc 。
- 如果内存碎片率低于 1
Redis 实例可能会把部分数据交换到硬盘上。内存交换会严重影响 Redis 的性能,所以应该增加可用物理内存或减少 Redis 内存占用。
- 修改内存分配
Redis 支持 libc、jemalloc11、tcmalloc 三种不同的内存分配器,每个分配器在内存分配和碎片上都有不同的实现。不建议运维人员修改 Redis 默认内存分配器,因为这需要完全理解这几种内存分配器的差异,也要重新编译 Redis。这个方法更多的是让其了解 Redis 内存分配器所做的工作。
2:内存使用率
2.1:针对缓存数库大小选择
如果缓存数据小于 4GB,就使用 32 位的 Redis 实例。因为 32 位实例上的指针大小只有 64 位的一半,它的内存空间占用空间会更少些。 这样有一个坏处就是,假设物理内存超过 4GB,那么 32 位实例能使用的内存仍然会被限制在 4GB 以下。 要是实例同时也共享给其他一些应用使用的话,那可能需要更高效的 64 位 Redis 实例,这种情况下切换到 32 位是不可取的。 不管使用哪种方式,Redis 的 dump 文件在 32 位和 64 位之间是互相兼容的,因此倘若有减少占用内存空间的需求,可以尝试先使用 32 位,后面再切换到 64 位上。
2.2:使用Hash数据结构
一个减少内存使用率的简单方法就是,每当存储对象时确保设置 key 的过期时间。倘若 key 在明确的时间周期内使用或者旧 key 不大可能被使用时,就可以用 Redis 过期时间命令(expire, expireat, pexpire, pexpireat)去设置过期时间,这样 Redis 会在 key 过期时自动删除 key。 假如知道每秒钟有多少个新 key - value 被创建,那可以调整 key 的存活时间,并指定阈值去限制 Redis 使用的最大内存。
2.3:设置key的过期时间
当内存使用达到设置的最大阈值时,需要选择一种 key 的回收策略,可在 redis.conf 配置文件中修改 “maxmemory - policy” 属性值。默认情况下回收策略是禁止删除,若是 Redis 数据集中的 key 都设置了过期时间,那么 “volatile - ttl” 策略是比较好的选择。但如果 key 在达到最大内存限制时没能够迅速过期,或者根本没有设置过期时间。那么设置为 “allkeys - lru” 值比较合适,它允许 Redis 从整个数据集中挑选最近最少使用的 key 进行删除(LRU 淘汰算法)。Redis 还提供了一些其他淘汰策略。
3:回收key
volatile - lru:使用 LRU 算法从已设置过期时间的数据集合中淘汰数据;
volatile - ttl:从已设置过期时间的数据集合中挑选即将过期的数据淘汰;
volatile - random:从已设置过期时间的数据集合中随机挑选数据淘汰;
allkeys - lru:使用 LRU 算法从所有数据集合中淘汰数据;
allkeys - random:从数据集合中任意选择数据淘汰;
no - eviction:禁止淘汰数据。