当前位置: 首页 > news >正文

NoSQL之Redis配置与优化

目录

关系数据库与非关系型数据库

关系型数据库

非关系型数据库

非关系型数据库产生背景

Redis基础简介

Redis安装部署

配置参数

Redis命令工具

redis-cli命令行工具

redis-banchmark测试工具

Redis数据库常用命令

key相关命令

多数据库常用命令

Redis持久化

RDB和AOF的区别

RDB优点

RDB缺点

AOF优点

AOF缺点

Redis持久化配置

RDB持久化配置

AOF持久化配置

AOF重写

性能管理

内存碎片率

内存使用率

针对缓存数据大小选择

使用Hash数据结构

设置key的过期时间

回收key


关系数据库与非关系型数据库

数据库按照数据库的结构可以分为关系型数据库与其他数据库,而这些其他
数据库我们将其统称为非关系型数据库。

关系型数据库

关系型数据库是一个结构化的数据库,创建在关系模型基础上,一般面向于
记录。它借助于集合代数等数学概念和方法来处理数据库中的数据。关系模型就
是指二维表格模型,因而一个关系型数据库就是由二维表及其之间的联系组成的
一个数据组织。现实世界中,各种实体与实体之间的各种联系都可以用关系模型
来表示。SQL语句(标准数据查询语言)就是一种基于关系型数数据库的语言,用
于执行对关系型数据库中数据的检索和操作。主流的关系型数据库包括Oracle、MySQL、SQL Server、Micrrosoft AccessDB2等等

非关系型数据库

NoSQL(NoSQL = Not Only SQL),意思是"不仅仅是SQL",是非关系型数
据库的总称。主流的NoSQL数据库有Redis、MongBD、Hbase、CouhDB等等。
以上这些非关系型数据库,他们的存储方式、存储结构以及使用的的场景都是完全
不同的。所以我们认为它是一个非关系型数据库的集合,而不是像关系型数据库
一样,是一个统称。换言之,除了主流的关系型数据库以外的数据库,都可以认
为是非关系型的。NoSQL数据库凭借着其非关系型、分布式、开源及横向扩展等
优势,被认为是下一代数据库产品

非关系型数据库产生背景

随着Web2.0网站的兴起,关系型数据库在应应对Web2.0网站,特别是海量
数据和高并发的SNS(Social Networking Services,即社交网网络服务)类型的
Web2.0纯动态网站时,暴露出很多难以解决的问题,例如三高高问题
(1)High performance--对数据库高并发读写需求
Web2.0网站会根据用户的个性化信息来实时生成动态页面和提供动态信息,
因此无法使用动态页面静态化技术。所以数据库的并发负载非?常高,一般会达到
10000次/s以上的读写请求。关系型数据库对于上万次的查询请求还是可以勉
强支撑的,但出现上万次的写数据请求,硬盘I0就已经无法承受了。对于普通
的BBS网站,往往也会存在高并发的写数据请求。
(2)HugeStorage--对海量数据高效存储与访问需求
类似于Facebook、Friendfeed这样的SNS网站,每天会产生生大量的用户
动态信息。如Friendfeed,一个月就会产生不少于2.5亿条用户动态信息,对
于关系型数据库来说,在一个包含2.5亿条记录的表中执行SQL查询,查询效
率是非常低的。(3) High Scalability & High Availability-
对数据库高可扩展性与高
可用性需求在Web架构中,数据库是最难进行横向扩展的。当应用系统的用
户量与访问量与日俱增时,数据库是没办法像Web服务一样,简单地通过添加
硬件和服务器节点来扩展其性能和负载能力的。尤其对于一些需要24小时对外
提供服务的网站来说,数据库的升级与扩展往往伴随着停机维护与数据迁移,其
工作量是非常庞大的。关系型数据库和非关系型数据库都有各自的特点与应用场景,两有的紧密结合将会给Web2.0的数据库发展带来新的思路。让关系数据库关注在关系上,非关系型数据库关注在存储上。例如,在读写分离的MySQL数据库环境中,可以把
经常访问的数据存储在非关系型数据库中,提升访问速度。

Redis基础简介

Redis服务器程序是单进程模型,也就是在一台服务器上可以同时启动多个
Redis进程,而Redis的实际处理速度则是完全依靠于主进程的执行效率。若
在服务器上只运行一个Redis进程,当多个客户端同时访问时,服务器的处理
能力是会有一定程度的下降;若在同一台服务器上开启多个Redis进程,Redis
在提高并发处理能力的同时会给服务器的CPU造成很大压力。即:在实际生产
环境中,需要根据实际的需求来决定开启多少个Redis进程。若对高并发要求
更高一些,可能会考虑在同一台服务器上开启多个进程。若CPU资源比较紧张,
采用单进程即可。具有极高的数据读写速度,数据读取的速度最高可达到1100000次/s,数据写入速度最高可达到81000次/s。支持丰富的数据类型,不仅仅支持简单的key-value类型的数据,还支持Strings,Lists,Hashes,Sets及Ordered Sets等数据类型操作
支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再
次加载进行使用。原子性,Redis所有操作都是原子性的。支持数据备份,即master-salve模式的数据备份。Redis作为基于内存运行的数据库,缓存是其最常应用的场景之一。除比之外,Redis常见应用场景还包括获取最新N个数据的操作、排行于榜类应用、计
数器应用、存储关系、实时分析系统、日志记录。

Redis安装部署

Redis的安装相对于其他服务来说比较简单。首先需要到Redis官网(htt
ps://www.redis.io)下载相应的源码软件包,然后上传至Linux系统的服务器
中进行解压、安装。本章中以redis-4.0.9.tar.gz为例进行Redis服务的安
装和配置讲解。
通常情况下,在Linux系统中进行源码编译安装,需要先执行亍./configure
进行环境检查与配置,从而生成Makefile文件,再执行makte & make install
命令进行编译安装。而Redis源码包中直接提供了Makefile文件,所以在解
压完软件包后,可直接进入解压后的软件包目录,执行make 与make install
命令进行安装。

[root@localhost src]# dnf -y install tar gcc make
[root@localhost src]# tar xvzf redis-4.0.9. tar. gz
[root@localhost src]# cd redis-4.0.9/
[root@localhost_redis-4.0.9]# make
[root@localhost redis-4.0.9]# make PREFIX=/usr/local/redis install
[root@localhost `]# ln -s /usr/local/redis/bin/* /ussr/local/bin/

 makeinstall只是安装了二进制文件到系统中,并没有启动脚本和配置文件。
软件包中默认提供了一个install_server.sh脚本文件,通过该脚本文件可以
设置Redis服务所需要的相关配置文件。当脚本运行完毕,Redis服务就已经
启动,默认侦听端口为6379。

[root@localhost redis-4.0.9]# cd utils,
[root@localhost utils]# ./install_server.sh

[root@localhost_utils]# netstat -lnupt | grep redis
tcp 0 0 127.0.0.1:6379 0.0.0.0.0:* LISTEN 5494/rediis-server 1

配置参数

Redis主配置文件为/etc/redis/6379.conf,由注释行与设置置行两部分组成
与大多数Linux配置文件一样,注释性的文字以"#"开始,包含了对相关配置
内容进行的说明和解释。除了注释行与空行以外的内容即为设置行。可根据生产
环境的需求调整相关参数,如下:

[root@localhost]# vi /etc/redis/6379.conf
bind 127.0.0.1 192.168.10.161//监听的主机地址
port 6379//端口
daemonizeyes//启用守护进程
pidfile/var/run/redis_6379.pid//指定PID文件
loglevel notice//日志级别
logfile/var/log/redis_6379.log//指定日志文件
[root@localhost~]#/etc/init.d/redis 6379 restart
Stopping...
Redis stopped
Starting Redis server...

参数作用
timeout 300当客户端闲置多长时间后关闭连接,如果指定为0,
表示关闭该功能
dbfilename dump.rdb指定本地数据库文件名,默认值为dump.rdb
dir/var/lib/redis/6379指定本地数据库存放目录
maxclients 10000设置同一时间最大客户端连接数,默认为10000。
Redis可以同时打开的客户端连接数为Redis进程可
以打开的最大文件描述符数,如果设置maxclients
0,表示不限制。当客户端连接数到达限制时,Redis
会关闭新的连接并向客户端返回maxnumberof
clients reached 错误信息
rdbcompression yes指定存储至本地数据库时是否压缩数据,默认为yes,
Redis采用LZF压缩,如果为了节省CPU资源,可
以关闭该选项,但会导致数据库文件变的巨大
slaveof <masterip><masterport><masterport>当本机为从服务器时,设置主服务的IP地址及端口。
在Redis启动时,从服务器会自动从主服务进行数据
同步
masterauth <master-password>当主服务设置了密码保护时,从服务连接主服务的密码
requirepass foobared设置
Redis连接密码,如果配置了连接密码,客户端
在连接Redis时需要通过AUTH<password>命令提
供密码,默认关闭
maxmemory <bytes>指定Redis最大内存限制。Redis在启动时会把数据
加载到内存中,达到最大内存后,Redis会先尝试清
除已到期或即将到期的Key,当此方法处理后,仍然
到达最大内存设置,将无法再进行写入操作,但仍然
可以进行读取操作。Redis新VM机制,会把Key存
放内存,Value会存放在Swap分区
appendonly no指定是否在每次更新操作后进行日志记录,Redis在
默认情况下是异步地把数据写入磁盘,如果不开启,
可能会在断电时导致一段时间内的数据丢失。因为
Redis本身同步数据文件是按上面save条件来同步
的,所以有的数据会在一段时间内只存在于内存中。
默认为no
appendfilename appendonly.aof指定更新日志文件名,默认为appendonly.aof
appendfsync everysec指定更新日志条件,共有3个可选值:
no:表示等操作系统进行数据缓存同步到磁盘(快)
always:表示每次更新操作后手动调用fsync()将数据
写到磁盘(慢,安全
everysec:表示每秒同步一次(折衷,默认值)
activerehashing yes指定是否激活重置哈希,默认为开启
include/path/to/local.conf指定包含其它的配置文件,可以在同一主机上多个
Redis实例之间使用同一份配置文件,而同时各个实
例又拥有自己的特定配置文件

Redis命令工具

redis-server:用于启动 Redis的工具;
redis-benchmark:用于检测Redis在本机的运行效率;
redis-check-aof:修复AOF持久化文件;
redis-check-rdb:修复RDB持久化文件;
redis-cli:Redis 命令行工具。

redis-cli命令行工具

[root@localhost ^]# /usr/local/redis/bin/redis-cli //连接本机Redis数
据库
127.0.0.1:6379>ping//检测 redis服务是否启动
PONG
127.0.0.1:6379)

 

[root@localhost ^]#redis-cli -h 192.168.10.161 -p 6379
192.168.10.161:6379>info
# Server
redis_version:4.0.9
redis_git_shal:00000000
redis_git_dirty:0
redis_build_id:7f55f2cla630cbe5
192.168.10.161:6379>exit

redis-banchmark测试工具

-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格式输出;
-1:生成循环,永久执行测试;
-t:仅运行以逗号分隔的测试命令列表;
-I:Idle模式。仅打开 N个 idle连接并等待。

结合上述选项,可以针对某台Redis服务器进行性能检测,如执行
redis-benchmark -h 192.168. 10.161 -p 6379 -c 100 -n 100000命令即可向IP
地址为192.168.10.161、端口为6379的Redis服务器发送100个并发连接
与100000个请求测试性能。

[root@localhost ^]# redis-benchmark -h 192.168.10.161 -p 6379 -c 100 -n
100000
8225.04 requests per second
MSET (10 keys) =======
100000 requests completed in 1.57 seconds
100 parallel clients
3 bytes payload
keep alive: 1
24.75% <= 1 milliseconds
<= 2 milliseconds
99.02%
99.57% <= 3 milliseconds
99.90% <= 4 milliseconds
99.98% <= 5 milliseconds
100.00% <= 5 milliseconds
63653.72 requests per second

 执行redis-benchmark-h 192.168.10.161-p 6379 -p -d 100命令的作用是
测试存取大小为100字节的数据包的性能。

[root@localhost *]#redis-benchmark -h 192.168. 168. 10.161 -p 6379 -q -d 100
PING_INLINE: 88261.25 requests per second
PING_BULK: 90991.81 requests per second
SET: 83612.04 requests per second
GET: 84961.77 requests per second
INCR: 83682.01 requests per second
LPUSH: 76745.97 requests per second
RPUSH: 78247.26 requests per second
LPOP: 77519.38 requests per second
RPOP: 79681.27 requests per second
SADD: 83125.52 requests per second
SPOP: 85543.20 requests per second
LPUSH (needed to benchmark LRANGE) : 78864.35 requestsper second
(first 100 elements): 30931.02 requests per second
LRANGE 100
LRANGE 300
(first 300 elements): 9437.52 requests per second
LRANGE_500 (first 450 elements): 5541.39 requests persecond
LRANGE_600 (first 600 elements): 3824.38 requests persecond
MSET (10 keys) : 64184.86 requests per second

Redis数据库常用命令

set:存放数据,基本的命令格式为setkeyvalue。
get:获取数据,基本的命令格式为 get key。

key相关命令

keys exists del type rename renamenx dbsize

多数据库常用命令

Redis支持多数据库,Redis在没有任何改动的情况下默认包含16个数据
库,数据库名称是用数字0-15来依次命名的。使用select命令可以进行
Redis的多数据库之间的切换,命令格式为selectindex,其中index表示数据库的序号。而使用redis-cli连接Redis数据库后,默认使用的是序号为0的
数据库。如下所示,使用select命令切换数据库后,会在前端的提示符中显示当前
所在的数据库序号如"127.0.0.1:6379[10]>"表示当前使用的是序号为10的
数据库。若当前使用的数据库是序号为0的数据库,提示符中则不显示序号,
如"127.0.0.1:6379>"表示当前使用的是序号为0的数据库。Redis的多数据库在一定程度上是相对独立的,例如在数据库0上面存放
kl的数据,在其它1-15的数据库上是无法查看到的。Redis数据库提供了一个move的命令,可以进行多数据库之间的数据移动。命
令的基本语法格式为"movekeydbindex"。其中"key"表示当前数据库的目
标键,"dbindex"表示目标数据库的序号,具体操作方法如下所示。(3)清除数据库内数据
Redis数据库的整库数据删除主要分为两个部分:清空当前数据库数据,使用
FLUSHDB命令实现;清空所有数据库的数据,使用FLUSHALL命令实现。但是,
数据清空操作比较危险,生产环境下一般不建议使用。

Redis持久化

Redis是一种高级key-value数据库。它跟Memcached类似,不过数据可
以持久化,而且支持的数据类型很丰富,有字符串、列表、集合和有序集合。支
持在服务器端计算集合(difference)等,还支持多种排序功能。所以Redis也
可以被看成是一个数据结构服务器。
Redis的所有数据都是保存在内存中,然后不定期的通过异步方式保存到磁
盘上(这称为"半持久化模式");也可以把每一次数据变化都写有人到一个 append
onlyfile(aof)里面(这称为"全持久化模式")。
由于Redis的数据都存放在内存中,如果没有配置持久化,Redis重启后
数据就全丢失了。所以,需要开启Redis的持久化功能,将数据保存到磁盘上,
当Redis重启后,可以从磁盘中恢复数据。Redis提共两种方式进行持久化,
一种是RDB持久化(原理是将Reids在内存中的数据库记录定时dump到磁盘
上的RDB持久化),另外一种是AOF(appendonlyfile)持久化(原理是将Reids
的操作日志以追加的方式写入文件)。那么这两种持久化方式有什么区别呢?在
实际使用的时候该如何选择呢?下面简单介绍一下二者的区别。

RDB和AOF的区别

RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际
操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件AOF持久化以日志的形式记录服务器所处理的每一个写、册删除操作,查询操
作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录

RDB优点

一旦采用该方式,那么整个Redis数据库将只包含一个文件,这对于文件
备份而言是非常完美的。比如,计划每个小时归档一次最近24小时的数据,同
时还要每天归档一次最近30天的数据。通过这样的备份策略,一旦系统出现灾
难性故障,可以非常容易地进行恢复。
对于灾难恢复而言,RDB是非常不错的选择。可以非常轻松的将一个单独的
文件压缩后再转移到其它存储介质上。
性能最大化,对于Redis的服务进程而言,在开始持久化时,它唯一需要做
的只是fork出子进程,之后再由子进程完成这些持久比的工作,这样就可以极
大的避免服务进程执行 10操作了。
相比于AOF机制,如果数据集很大,RDB的启动效率会更高。

RDB缺点

如果想保证数据的高可用性,即最大限度的避免数据丢失,那么RDB将不是
一个很好的选择。因为系统一旦在定时持久化之前出现宕机现象象,此前没有来得
及写入磁盘的数据都将丢失。
由于RDB是通过fork子进程来协助完成数据持久化工作的,因此当数据集
较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟。

AOF优点

AOF机制可以带来更高的数据安全性,即数据持久性。Redis中提供了3种
同步策略,即每秒同步、每次修改同步和不同步。事实上,每秒同步也是异步完
成的,其效率也是非常高的,弊端是一旦系统出现宕机现象,那么这一秒钟之内
修改的数据将会丢失。而每次修改同步,可以将其视为同步寺久化,即每次发生
的数据变化都会被立即记录到磁盘中,这种方式在效率上是:最低的。
由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程
中即使出现 宕机现象,也不会破坏日志文件中已经存在的内容。然而如果本次
操作只是写入了一半数据就出现了系统崩溃问题,那么在Redis下一次启动之
前,可以通过 redis-check-aof工具来解决数据一致性的问题。
如果日志过大,Redis可以自动启用 rewrite机制。即Redis以append模
式不断地将修改数据写入到老的磁盘文件中,同时Redis记还会创建一个新的文
件用于记录此期间有哪些修改命令被执行。因此在进行rewrite切换时可以更
好的保证数据安全性。
AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。事
实上,也可以通过该文件完成数据的重建。

AOF缺点

对于相同数量的数据集而言,AOF文件通常要大于RDB文件牛。RDB在恢复大
数据集时的速度比AOF的恢复速度要快。
根据同步策略的不同,AOF在运行效率上往往会慢于RDB。每秒同步策略的
效率是比较高的,同步禁用策略的效率和RDB一样高效。
二者选择的标准,就是看系统是愿意牺牲一些性能,换取更高的缓存一致性
(AOF),还是愿意写操作频繁的时候,不启用备份来换耶双更高的性能,待手动
运行save的时候,再做备份(RDB)。

Redis持久化配置

RDB持久化配置

Redis会将数据集的快照dump到dump.rdb文件中。此外,也可以通过配
置文件来修改Redis服务器dump快照的频率。在打开6379.conf文件之后,
搜索save,可以看到如下所示配置信息。
save 900 1:在900秒(15分钟)内,如果至少有1个 key发生变化
则dump内存快照。
save30010:在300秒(5分钟)内,如果至少有10个key发生变化,
则dump内存快照。save60 10000:在60秒(1分钟)内,如果至少有10000个key艺生变
化,则dump内存快照。

AOF持久化配置

appendonlyno改为yes开启aof。
在Redis的配置文件中存在三种同步方式,它们分别是:
appendfsyncalways:每次有数据修改发生时都会写入AOF文件#。
appendfsynceverysec:每秒钟同步一次,该策略为AOF的每快省策略。
appendfsync no:从不同步,高效但是数据不会被持久化。

AOF重写

Redis会不断地将被执行的命令记录到AOF文件里面,所以随着Redis不
断运行,AOF文件的体积也会不断增长。在极端情况下,体积不不断增大的AOF文
件甚至可能会用完硬盘的所有可用空间。Redis在重启之后需要通过重新执行
AOF文件记录的所有写命令来还原数据集,所以如果AOF文件的体积非常大,
那么还原操作执行的时间就可能会非常长。
为了解决 AOF 文件体积不断增大的问题,用户可以向Redis发送
BGREWRITEAOF命令。BGREWRITEAOF 命令会通过移除AOF 文件中的冗余命令来
重写(rewrite)AOF文件,使AOF文件的体积尽可能地变小。
BGREWRITEAOF的工作原理和BGSAVE创建快照的工作原理非常相似:Redis
会创建一个子进程,然后由子进程负责对AOF文件进行重写。因为AOF文件重
写也需要用到子进程,所以快照持久化因为创建子进程而导致的性能问题和内存
占用问题,在AOF持久化中也同样存在。
与快照持久化通过设置save选项来自动执行BGSAVE样,AOF持久化也
可以通过设置auto-aof-rewrite-percentage选项和auto-aof-rewrite
min-size选项来自动执行BGREWRITEAOF。

性能管理

Redis性能管理需要关注的数据指标有内存使用率、内存碎片率、回收 key
等。这其中有些数据可以通过进入info命令进行查看。需要查看某一项的值就
后面跟具体参数,执行以下命令查看Redis使用内存值直

192.168.9.236:7001>infomemory
# 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:626859900
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
used_memory scripts:0
used_memory_scripts_human:OB
number_of_cached_scripts:0
maxmemory:17179869184
maxmemory_human: 16.00G
maxmemory_policy:allkeys-lru
allocator_frag_ratio:1.01
allocator_frag_bytes:14714128
allocator_rss_ratio:1.03
allocator_rss_bytes:49356800
rss_overhead ratio:0.99
rss_overhead_bytes:-19152896
mem_fragmentation_ratio:1.03
mem_fragmentation_bytes:45321664
mem_not_counted_for_evict:0
mem_replication backlog:536870912
mem_clients_slaves:16922
mem_clients_normal:218914
mem aof buffer:0
mem allocator: jemalloc-5.1.0
active_defrag_running:0
lazyfree_pending objects:0

内存碎片率

除了用户定义的数据和内部开销以外,used_memory_rss指标还包含了内存
碎片的开销,内存碎片是由操作系统低效的分配/回收物理内存导致的操作系
统负责分配物理内存给各个应用进程,Redis使用的内存与物理内存的映射是由
操作系统上虚拟内存管理分配器完成的。
举例来说:Redis需要分配连续内存块来存储1G的数据集。如果物理内存
上没有超过1G的连续内存块,那操作系统就不得不使用多个不连续的小内存块
来分配并存储这1G数据,该操作就会导致内存碎片的产生三。
内存分配器另一个复杂的层面是,系统会预先分配一下内存区块应用程序
这样可以加块应用程序运行速度,但会产生另外一个问题,就是预先分配内存区
块大小的问题。比如运行一个5G大小应用,需要5个1G大小的内存区块,
结果系统就分配了5个2G的内存区块,这样就浪费了5G的运行内存空间,
同样就产生内存碎片率。
内存碎片率对理解Redis实例的资源性能是非常重要的。内存碎片率稍大
于1是合理的,这个值表示内存碎片率比较低,也说明Redis没有发生内存交
换。但如果内存碎片率超过1.5,那就说明Redis消耗了实际需要物理内存的
150%,其中50%是内存碎片率。若是内存碎片率低于1的话,说明Redis内存
分配超出了物理内存,操作系统正在进行内存交换。内存交换会引起非常明显的
响应延迟。若生产环境内存碎片率过高,会导致Redis性能降低。解决该情况的常见方案有三种。内存碎片率超过1.5重启Redis服务器可以让额外产生的内存碎片失效并重新作为新内存来使用,使操作系统恢复高效的内存管理。额外碎片的产生是由于Redis释放了内存块,但内存分配器并没有返回内存给操作系统,这个内存分配器是在编译时指
定的,可以是libc、jemalloc或者tcmalloc 。
通过比较used_memory_peak, used_memory_rss #fa used_memory_metrics p的数据指标值可以检查额外内存碎片的占用。从名字上可以看出,used_memory_peak是过去
Redis内存使用的峰值,而不是当前使用内存的值。如果useed_memory_peak和
used_memory_rss的值大致上相等,而且二者明显超过
了used_memory值,这说明额外的内存碎片正在产生。在重启服务器之前,需
要在redis-cli工具上输入shutdownsave命令,表示强制让Redis数据库
执行保存操作并关闭Redis服务,这样做能保证在Redis关闭时不不丢失任何数
据。在重启后Redis会从硬盘上加载持久化的文件,以确保数据集持续可用。
如果内存碎片率低于1
Redis实例可能会把部分数据交换到硬盘上。内存交换会严重影响Redis的
性能,所以应该增加可用物理内存或减少Redis内存占用。
修改内存分配Redis支持 libc、jemallocll、tcmalloc 三种不同的内存分配器,每个分
配器在内存分配和碎片上都有不同的实现。不建议运维人员修改Redis默认内
存分配器,因为这需要完全理解这几种内存分配器的差异,也要重新编译Redis。
这个方法更多的是让其了解Redis内存分配器所做的工作。

内存使用率

内存使用率是Redis服务最关键的一部分。如果一个Redis实例的内存使
用率超过可用最大内存,那么操作系统开始进行内存与swap空间交换,把内存
中旧的或不再使用的内容写入硬盘上(硬盘上的这块空间叫swap分区),以便
腾出新的物理内存给新页或活动页(page)使用。
used_memory字段数据表示的是由Redis分配器分配的内存总量,以字节
为单位。共中used_memory_human上的数据和used_memory是一样的值,它以
M为单位显示,目的是为了方便阅读。
used_memory是Redis使用的内存总量,它包含了实际缓存占用的内存和
Redis自身运行所占用的内存(如元数据、lua)。它是由Redis使用内存分配器
分配的内存,所以这个数据并没有把内存碎片浪费掉的内存给统计进去。Redis
默认最大使用内存是可用物理内存剩余的所有内存,0代表没有限限制
在硬盘上进行读写操作要比在内存上进行读写操作慢很多。如果Redis进
程上发生内存交换,那么Redis和依赖Redis上数据的应用用会受到严重的性能
影响。通过查看used_memory指标可知道Redis正在使用用的内存情况,如果
used_memory大于可用最大内存,那就说明Redis实例正在进行内存交换或者
已经完成内存交换。运维人员应该根据这个情况执行相应的应急措施。

针对缓存数据大小选择

如果缓存数据小于4GB,就使用32位的Redis实例。因为32位实例上
的指针大小只有64位的一半,它的内存空间占用空间会更少些。这样有一个
坏处就是,假设物理内存超过4GB,那么32位实例能使用的内存仍然会被限制
在4GB以下。要是实例同时也共享给其他一些应用使用的话,那可能需要更高
效的64位Redis实例,这种情况下切换到32位是不可取的。不管使用哪种
方式,Redis的dump文件在32位和64位之间是互相兼容的,因此倘若有减
少占用内存空间的需求,可以尝试先使用32位,后面再切换了到64位上。

使用Hash数据结构

因为Redis在储存小于100个字段的Hash结构上,其存储效率是非常高
的。所以在不需要集合(set)操作或list的push/pop操作时,房可能的使用
Hash结构。例如在一个Web应用程序中,需要存储一个对象表示用户信息,使
用单个key表示一个用户,其每个属性存储在Hash的字段里,这样要比给每
个属性单独设置一个key-value要高效的多。通常情况下下倘若有数据使用
string结构,用多个key存储时,那么应该转换成单key多字段的Hash结
构。如上述例子中介绍的Hash结构应包含单个对象的属性或者单个用户各种各
样的资料。Hash结构的操作命令是HSET(key,fields,vallue)和HGET(key,
field),使用它可以存储或从Hash中取出指定的字段。

设置key的过期时间

一个减少内存使用率的简单方法就是,每当存储对象时确保设置key的过
期时间。倘若key在明确的时间周期内使用或者旧key不大可能皮使用时,就
可以用Redis过期时间命令(expire,expireat,pexpire,pexpireat)去设置过
期时间,这样Redis会在key过期时自动删除key。假如知道每秒钟有多少
个新key-value被创建,那可以调整 key的存活时间,并指定阀值去限制
Redis使用的最大内存。

回收key

当内存使用达到设置的最大阀值时,需要选择一种 key的回收策略,可在
redis.conf配置文件中修改"maxmemory-policy"属性值。默认情况下回收策
略是禁止删除,若是Redis数据集中的 key都设置了过期时间,那么
"volatile-ttl"策略是比较好的选择。但如果key在达到最大内存限制时没
能够迅速过期,或者根本没有设置过期时间。那么设置为"allkeys-1ru"
值比较合适,它允许Redis从整个数据集中挑选最近最少使用的key进行删除
(LRU淘汰算法)。Redis还提供了一些其他淘汰策略。
volatile-lru:使用LRU算法从已设置过期时间的数据集合中淘汰数据:volatile-ttl:从已设置过期时间的数据集合中挑选即将过期的数据淘汰;
volatile-random:从已设置过期时间的数据集合中随机挑选数据淘汰:
allkeys-lru:使用LRU算法从所有数据集合中淘汰数据:
allkeys-random:从数据集合中任意选择数据淘汰;
no-enviction:禁止淘汰数据。
infostats信息中的evicted_keys字段显示的是因为maxmemory限制导
致key被回收删除的数量。当Redis由于内存压力需要回收女一个key时,
Redis首先考虑的不是回收最旧的数据,而是在最近最少使用的key或即将过期的key中随机选择一个key,从数据中删除

192.168.9.236:7001> info stats
# Stats
total_connections_received:473156108
total_commands_processed:4180290178
instantaneous_ops_per_sec:375
total_net_input_bytes:14676967575477
total_net_output_bytes:102221322391862
instantaneous_input_kbps:1465.97
instantaneous_output_kbps:7011.15
rejected_connections:0
sync_full:1
sync_partial_ok:0
sync_partial_err:1
expired_keys:34158591
expired_stale_perc:0.40
expired_time_cap_reached_count:0
evicted_keys:0
keyspace_hits:3089647498
keyspace_misses:94699798
pubsub_channels:3
pubsub_patterns:2
latest_fork_usec:51400
migrate_cached_sockets:0
slave_expires_tracked_keys:0
active defrag hits:0
active defrag_misses:0
active defrag_key_hits:0
active defrag_key_misses:0

通过以上文字描述和参数对比,可以根据key的回收来定位性能问题,通
过回收key可以保证合理分配Redis有限的内存资源。因此evicted_keys值
经常超过0,那应该会看到客户端命令响应延迟时间增加,因为Redis不但要
处理客户端过来的命令请求,还要频繁的回收满足条件的key
需要注意的是,回收 key对性能的影响远没有内存交换严重,若是在强制
内存交换和设置回收策略做一个选择的话,则放弃强制内存交换是比较合理的,因为把内存数据交换到硬盘上对性能影响非常大。既然频繁的回收key也会导
致性能问题,需要减少回收 key来提升性能,根据经驯脸如果开启快照功能
maxmemory需要设置成物理内存的45%,这几乎不会有引发内不存交换的危险。若
是没有开启快照功能,设置系统可用内存的95%是比较合理的。
另外一种分片技术是把数据分割成合适大小,分别存放在不同的Redis实
例上,每一个实例都包含整个数据集的一部分。通过分片可以把很多服务器联合
起来存储数据,相当于增加总的物理内存,使其在没有内存交换和回收key的
策略下也能存储更多的keyg假如有一个非常大的数据集,maxmeemory已经设置,
实际内存使用也已经超过了推荐设置的阀值,通过数据分片能明显减少key的
回收,从而提高Redis的性能。当然Redis性能管理远远
比上面列出的几种复杂的多,需要多加学习。

相关文章:

  • Java高级 | 【实验五】Spring boot+mybatis操作数据库
  • 游戏设计模式 - 子类沙箱
  • 微服务架构下的服务注册与发现:Eureka 深度解析
  • day20 leetcode-hot100-38(二叉树3)
  • 基于大数据爬虫+智能AI的网络小说数据可视化系统设计与实现
  • Excel自动分列开票工具推荐
  • EXCEL通过DAX Studio获取端口号连接PowerBI
  • EXCEL如何快速批量给两字姓名中间加空格
  • XHR / Fetch / Axios 请求的取消请求与请求重试
  • 箭头函数 vs 普通函数:区别与使用场景
  • 基于Pandas数据分析的设备巡检计划生成算法设计及实现
  • AI驱动游戏开发:Unity与ML-Agents结合
  • 数据库优化实战分享技术文章大纲
  • mysql跨库关联查询及视图创建
  • 国内头部的UWB企业介绍之品铂科技
  • Selenium 查找页面元素的方式
  • 企业培训学习考试系统源码 ThinkPHP框架+Uniapp支持多终端适配部署
  • STM32手册上标称的18MHz GPIO翻转速度和你实际测量到的速度之间的差异是预期之内且合理的
  • WebRTC中的几个Rtp*Sender
  • day028-Shell自动化编程-判断进阶
  • 织梦cms如何做网站/什么叫优化关键词
  • 网站首页做几个关键词/营销网页
  • 专业格泰建站/搜索引擎优化的流程
  • joomla 宠物网站模板/java培训机构
  • 做网站和做app那个简单/网站维护收费标准
  • 做网站需要什么技术员/百度推广工具有哪些