NoSQL之 Redis配置与优化

1.关系数据库和非关系数据库

关系数据库SQL 非关系数据库NoSQL
存储结构 二维表格结构 非二维表格结构,不同的NoSQL采用不同的存储方式(比如键值对、文档、索引、图形结构、时间序列等)
扩展方式 纵向扩展(提升单机的硬件性能) 横向扩展(增加服务器节点节点数量)
事务支持 基于ACID原则,对事物控制更稳定,细粒度更高 基于BASE原则,对事物控制的稳定性和细粒度不如SQL
典型代表 MySQL、Oracle、PostgreSQL、SQL Server、Microsoft Access、DB2 Redis、MongBD、Hbase、Memcached、ElasticSearch、TSDB

2.Redis安装部署

(1)Redis简介

用C语言开发的,开源的,基于内存运行的NoSQL并支持持久化。
存储结构:键值对(Key/Value KV)
数据类型:
五大基础类型:string(字符串)、list(列表)、hash(哈希/散列)、set(集合/无序集合)、zset/sorted set(有序集合)
三种特殊的数据类型:HyperLogLogs(基数统计) Bitmaps(位图) geospatial(地理位置)
端口号:TCP/6379

(2)Redis 为什么那么快?

1)redis是基于内存运行,数据的读写都是在内存中完成的
2)数据结构简单,可以直接使用 键值对 的方式存储数据
3)数据读写采用单线程模型,避免了多线程切换带来的CPU性能损耗,同时也不用考虑各种锁的影响
4)采用IO多路复用模型,非阻塞IO可以使网络线程处理更多的网络连接请求,提高了网络并发能力

(3)Redis安装部署

(1)环境准备

systemctl stop firewalld
systemctl disable firewalld
setenforce 0
vim /etc/selinux/config
        disabled

#修改内核参数
vim /etc/sysctl.conf
vm.overcommit_memory = 1       #内核允许超量使用内存直到用完为止,防止OOM杀死进程
net.core.somaxconn = 2048       #指定处于监听状态的连接请求队列的最大长度

sysctl -p



(2)安装redis

yum install -y gcc gcc-c++ make
cd /opt/
ls
rz -E 上传redis-7.0.13.tar.gz
tar xf redis-7.0.13.tar.gz
cd redis-7.0.13/
make
make PREFIX=/usr/local/redis install
cd /usr/local/redis/
ls
cd bin/
ls
#由于Redis源码包中直接提供了 Makefile 文件,所以在解压完软件包后,不用先执行 ./configure 进行配置,可直接执行 make 与 make install 命令进行安装。
#创建redis工作目录
mkdir /usr/local/redis/{conf,log,data}
ls
cd /opt/redis-7.0.13/
ls
cp redis.conf /usr/local/redis/conf/
useradd -M -s /sbin/nologin redis
chown -R redis:redis /usr/local/redis/

#环境变量
cd /usr/local/redis/bin/
ls
vim /etc/profile 
export PATH=$PATH:/usr/local/redis/bin		

source /etc/profile








(3)修改配置文件









(4)定义systemd服务管理脚本

[Unit]
Description=Redis Server
After=network.target

[Service]
User=redis     
Group=redis    
Type=forking   
TimeoutSec=0
PIDFile=/usr/local/redis/log/redis_6379.pid
ExecStart=/usr/local/redis/bin/redis-server /usr/local/redis/conf/redis.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target




-h :指定远程主机
-p :指定 Redis 服务的端口号
-a :指定密码,未设置数据库密码可以省略-a 选项

redis-server:Redis 服务器启动命令
redis-benchmark:性能测试工具,用于检测 Redis 在本机的运行效率
redis-check-aof:修复有问题的 AOF 持久化文件
redis-check-rdb:修复有问题的 RDB 持久化文件
redis-cli:Redis 客户端命令行工具
redis-sentinel:Redis 哨兵集群使用

(4)redis-benchmark 测试工具

redis-benchmark [选项] [选项值]

常见选项
-h 指定服务器主机名
-p 指定服务器端口
-s 指定服务器 socket
-c 指定并发连接数
-n 指定请求数
-d 以字节的形式指定 SET/GET 值的数据大小
-k 1=keep alive 0=reconnect
-r SET/GET/INCR 使用随机 key, SADD 使用随机值
-P 通过管道传输请求
-q 强制退出 redis。仅显示 query/sec 值
--csv 以 CSV 格式输出
-l 生成循环,永久执行测试
-t 仅运行以逗号分隔的测试命令列表
-I Idle 模式。仅打开 N 个 idle 连接并等待
redis性能压测攻击 
redis-benchmark -h <redis服务器地址> -p <redis端口> -a <redis密码> -c <并发连接数> -n <总请求数> -d <请求的数据大小> -t <测试的命令列表> -q

redis命令行客户端工具 
redis-cli -h <redis服务器地址> -p <redis端口> -a <redis密码> [命令]



3.Redis数据库常用命令

set:存放数据,命令格式为 set key value
get:获取数据,命令格式为 get key

通用操作
del 键 删除键
type 键 查看键的数据类型
keys 键 查询键,支持通配符 * ?
exists 键 判断键是否存在
expire 键 秒数 为键设置过期时间
ttl 键 查看键当前的过期时间,-1 永不过期,-2 已过期
rename 键 新键 重命名键,会覆盖已存在的键
renamenx 键 新键 重命名键,不会覆盖已存在的键
dbsize 统计当前库中键的总数
config set requirepass '密码' 设置redis密码
config get requirepass 查看redis密码
select 库ID 切换库,默认库ID为 0~15
move 键 库ID 移动键到指定的库
flushdb 清空当前库所有键(慎用)
flushall 清空所有库所有键(慎用)

Redis 支持多数据库,Redis 默认情况下包含 16 个数据库,数据库名称是用数字 0-15 来依次命名的。
多数据库相互独立,互不干扰。
select 序号 ##多数据库间切换

注:使用 redis-cli 连接 Redis 数据库后,默认使用的是序号为 0 的数据库。

move 键名 序号 ##多数据库间移动数据







rename 源key 目标key

renamenx 源key 目标key


config set requirepass 密码 ##设置密码
config get requirepass ##查看密码(一旦设置密码,必须先验证通过密码,否则所有操作不可用)

(1)Redis 数据类型

string类型操作:(计数器)
set 键 值
get 键
setex 键 秒数 值       #创建键并设置过期时间
incr 键                #数字递增+1
decr 键                #数字递减-1
STRLEN 键              #统计键值的字符长度
mset 键1 值1 键2 值2
mget 键1 键2
list类型操作:(消息队列)
lpush 键 值1 值2 ....                #从左边开始插入元素
rpush 键 值1 值2 ....                #从右边开始插入元素
lrange 键 起始位置  终止位置         #起始位置 0表示左边开始的第一个元素,终止位置 -1表示到最后一个元素
lpop 键                              #显示并删除左边第一个元素
rpop 键                              #显示并删除右边第一个元素
lrem 键 N 值                         #从左边开始删除N个指定元素
llen 键                              #统计元素的数量
lindex 键 元素位置                   #查看第N个元素的值
linsert 键 before|after 元素 值      #在指定元素前|后插入
hash类型操作:(存储对象描述)
hset 键 字段 值
hmset 键 字段1 值1 字段2 值2 ....
hget 键 字段
hkeys 键           #查看所有的字段
hvals 键           #查看所有字段的值
hdel 键 字段        #删除指定字段
set类型操作:(抽奖,求交集、差集、并集)
sadd 键 值1 值2 ....         #元素不能重复
smembers 键                  #查看元素,无序的
srem 键 值1 值2 ...          #删除指定的元素
srandmember 键 N             #随便显示N个元素
scard 键                     #统计元素的数量
spop 键                      #随机显示并删除一个元素
smove 键1 键2 值             #将键1的元素移动到键2中
sinter 键1 键2               #求键1与键2的交集
sdiff 键1 键2                #求键1与键2的差集
sunion 键1 键2               #求键1与键2的并集
zset类型操作:(排行榜,热搜)
zadd 键 权重1 值1  权重2 值2  ....          #score权重是可以重复的,元素值是不可以重复的
zrange 键  起始位置  终止位置 [withscores]      #起始位置 0表示左边开始的第一个元素,终止位置 -1表示到最后一个元素
zrangebyscore 键 起始权重  终止权重 [limit N M]     #查看指定权重范围的元素,按score从小到大,limit N M 表示只显示第N个之后的M个元素(不包括第N个元素)
zrevrange 键  起始位置  终止位置                    #降序查看
zrevrangebyscore 键 起始权重  终止权重 [limit N M]  #按score从大到小查看
zcard 键              #统计元素的数量
zcount 键 起始权重  终止权重     #统计指定权重范围的元素数量
zrem 键  值1 值2 ...           #删除指定的元素
zincrby 键 权重 值              #添加新的元素或增加指定元素的权重

4.Redis 高可用

在Redis中,实现高可用的技术主要包括持久化、主从复制、哨兵和 Cluster集群
●持久化:持久化是最简单的高可用方法(有时甚至不被归为高可用的手段),主要作用是数据备份,即将数据存储在硬盘,保证数据不会因进程退出而丢失。
●主从复制:主从复制是高可用Redis的基础,哨兵和集群都是在主从复制基础上实现高可用的。主从复制主要实现了数据的多机备份,以及对于读操作的负载均衡和简单的故障恢复。缺陷:故障恢复无法自动化;写操作无法负载均衡;存储能力受到单机的限制。
●哨兵:在主从复制的基础上,哨兵实现了自动化的故障恢复。缺陷:写操作无法负载均衡;存储能力受到单机的限制。
●Cluster集群:通过集群,Redis解决了写操作无法负载均衡,以及存储能力受到单机限制的问题,实现了较为完善的高可用方案。

(1)Redis持久化

(1)RDB持久化:定时的将redis在内存中的数据进行快照并压缩保存到硬盘里
手动触发:bgsave命令
自动触发:满足配置文件中 save n m 的规则(在n秒内发生了m次数据更新就会自动触发);主从复制在做全量复制时;执行shutdown命令关闭数据库时
工作流程:redis父进程会fork子进程来进行RDB持久化快照保存内存数据到硬盘里,文件名:dump.rdb
优缺点:
RDB持久化保存的文件占用空间较小,网络传输快,恢复速度比AOF更快,性能影响比AOF更小;
实时性不如AOF,兼容性较差,持久化期间在fork子进程时会阻塞redis父进程




(2)AOF持久化:实时的以追加的方式将redis写操作的命令记录到aof文件中
工作流程:
命令追加(将写操作命令追到aof_buf缓冲区)
文件写入和同步(文件名:appendonly.aof,同步策略:appendfsync everysec|always|no)
文件重写(减少aof文件占用空间的大小和加快恢复速度,定期执行bgrewriteaof命令触发)
优缺点:
实时性比RDB更好,支持秒级持久化,兼容性较好;
持久化保存的文件占用空间更大,恢复速度更慢,性能影响更大,AOF文件重写期间在fork子进程时也会阻塞redis父进程,且IO压力更大




AOF缓存区的同步文件策略存在三种同步方式

5.Redis性能管理

(1)内存碎片

通过 info memory 命令查看内存的使用情况。
mem_fragmentation_ratio的值如果超过了1.5,建议可以考虑进行内存碎片的清理了。
mem_fragmentation_ratio的值如果小于1,说明物理内存不够真实数据的保存了,此时已经开始使用swap交换空间了,会导致redis性能的严重下降。应该考虑增加物理内存或减少redis内存占用。

config set activedefrag yes    #开启自动内存碎片清理
memory purge                   #手动内存碎片清理
注:由于内存碎片清理是redis主线程执行的,会发生阻塞。因此需要合理配置对应的参数和方式,保证redis的高性能。



内回收key
内存数据淘汰策略,保证合理分配redis有限的内存资源。
当达到设置的最大阀值时,需选择一种key的回收策略,默认情况下回收策略是禁止删除。

6.redis优化

1)开启AOF持久化,设置AOF刷盘策略为everysec(每隔1秒执行一次刷盘操作),只在业务低峰期执行AOF文件重写,减少磁盘的开销
2)缩短键值对存储长度,避免存储bigkey导致操作耗时
3)给key设置合理的过期时间,尽量避免大量key集中过期
4)设置内存上限(maxmemory),并设置内存数据淘汰策略(maxmemory-policy),一般最常使用的是volatile-lru(只删除最近最少访问并设置了过期时间的键)或 allkeys-lru
5)开启自动内存碎片清理(activedefrag yes)
6)开启lazy-free机制(lazyfree-lazy-eviction yes、lazyfree-lazy-expire yes、lazyfree-lazy-server-del yes),将删除过期key的操作放到后台线程执行,以减少删除对Redis主线程的阻塞
7)使用物理机而非虚拟机部署Redis服务,使用高速固态盘作为AOF日志的写入盘。
8)使用分布式架构(主从复制、哨兵模式、集群)增加读写速度,并实现高可用
9)禁用内存大页(echo never > /sys/kernel/mm/transparent_hugepage/enabled),因开启内存大页会导致fork的速度变慢,也会拖慢写操作的执行时间

(1)redis的三大缓存问题

正常情况下,大部分的访问请求应该是先被redis响应的,在redis那里得不到响应的小部分访问请求才会去请求MySQL数据库获取数据,这样MySQL数据库的负载压力是非常小的,且可以正常工作。
缓存雪崩/穿透/击穿问题的根本原因在于redis缓存命中率下降,大量请求会直接发给MySQL数据库,导致MySQL数据库压力过大而崩溃。

缓存雪崩:redis中大量不同的缓存key集体过期
缓存穿透:大量请求访问redis和MySQL数据库都不存在的资源
缓存击穿:redis中一个热点key过期,此时又有大量请求访问这个热点key



(1)缓存雪崩解决方案

使用随机数设置key的过期时间,防止集群过期
设置二级缓存
数据库使用排他锁,实现加锁等待

(2)缓存穿透解决方案

对空值也进行缓存
使用布隆过滤器进行判断拦截一定不存在的无效请求
使用脚本实时监控,进行黑名单限制

(3)缓存击穿解决方案

设置永不过期
预先对热点数据进行缓存预热
数据库使用排他锁,实现加锁等待

(2)如何保证MySQL和redis的数据一致性?

读取数据时,先从redis读取数据,如果redis没有,再从MySQL读取,并将读取到的数据同步到redis缓存中。
更新数据时,先更新MySQL数据,再更新redis缓存
删除数据时,先删除redis缓存,再删除MySQL数据
对于一些关键数据,可以使用定时任务,定时自动进行缓存预热,或使用MySQL触发器来实现同步redis缓存

posted @ 2024-07-07 23:02  无敌小鲁班  阅读(1)  评论(0编辑  收藏  举报