理论+实验·NoSQL之Redis配置与优化
一、关系数据库和非关系数据库
1.1 关系型数据库
1.2 非关系型数据库
1.3 非关系型数据库产生背景
-
High performance——对数据库高并发读写需求
-
Huge Storage——对海量数据高效存储与访问需求
-
High Scalability && High Availability——对数据库高可扩展性与高可用性需求
1.4 Redis简介
二、Redis安装部署
2.1 操作步骤
- 解压软件包
- make && make install
- 设置Redis相关配置文件
- 查看运行状态
2.2 编译安装Redis
[root@localhost ~]# tar zxvf redis-5.0.7.tar.gz -C /opt/
[root@localhost ~]# cd /opt/redis-5.0.7
[root@localhost redis-5.0.7]# make
[root@localhost redis-5.0.7]# make PREFIX=/usr/local/redis install
[root@localhost redis-5.0.7]# ln -s /usr/local/redis/bin/* /usr/local/bin/
2.3 设置Redis相关配置文件
[root@localhost ~]# cd /opt/redis-5.0.7/utils/
[root@localhost utils]# ./install_server.sh '//一直按回车'
Welcome to the redis service installer
This script will help you easily set up a running redis server
Please select the redis port for this instance: [6379]
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf]
Selected default - /etc/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log]
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379]
Selected default - /var/lib/redis/6379
Please select the redis executable path [/usr/local/bin/redis-server]
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/bin/redis-server
Cli Executable : /usr/local/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!
[root@localhost utils]# vim /etc/redis/6379.conf
...
bind 127.0.0.1 20.0.0.10 '//70行'
...
port 6379 '//93行'
...
daemonize yes '//137行'
...
pidfile /var/run/redis_6379.pid '//159行'
...
loglevel notice '//167行'
...
logfile /var/log/redis_6379.log '//172行'
...
2.4 Redis进程控制
[root@localhost utils]# /etc/init.d/redis_6379 status '//查看状态'
[root@localhost utils]# /etc/init.d/redis_6379 stop '//停止'
[root@localhost utils]# /etc/init.d/redis_6379 start '//启动'
[root@localhost utils]# /etc/init.d/redis_6379 restart '//重启'
2.5 Redis配置文件
-
配置参数(/etc/redis/6379.conf)
- bind ===>监听的主机地址
- port ===>端口
- daemonize yes ===>启用守护进程
- pidfile ===>指定PID文件
- loglevel notice ===>日志级别
- logfile ===>指定日志文件
2.6 Redis部署流程
#预安装环境
[root@localhost ~]# yum -y install gcc gcc-c++ make
#编译安装
[root@localhost ~]# tar zxvf redis-5.0.7.tar.gz -C /opt/
[root@localhost ~]# cd /opt/redis-5.0.7
[root@localhost redis-5.0.7]# make
[root@localhost redis-5.0.7]# make PREFIX=/usr/local/redis install
[root@localhost redis-5.0.7]# ln -s /usr/local/redis/bin/* /usr/local/bin/
#安装Redis
[root@localhost ~]# cd /opt/redis-5.0.7/utils/
[root@localhost utils]# ./install_server.sh '//一直按回车'
Welcome to the redis service installer
This script will help you easily set up a running redis server
Please select the redis port for this instance: [6379]
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf]
Selected default - /etc/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log]
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379]
Selected default - /var/lib/redis/6379
Please select the redis executable path [/usr/local/bin/redis-server]
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/bin/redis-server
Cli Executable : /usr/local/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!
#配置文件
[root@localhost utils]# vim /etc/redis/6379.conf
...
bind 127.0.0.1 20.0.0.10 '//70行'
...
port 6379 '//93行'
...
daemonize yes '//137行'
...
pidfile /var/run/redis_6379.pid '//159行'
...
loglevel notice '//167行'
...
logfile /var/log/redis_6379.log '//172行'
...
[root@localhost utils]# /etc/init.d/redis_6379 restart '//重启'
#登录Reids数据库
[root@localhost utils]# redis-cli -h 20.0.0.10 -p 6379
20.0.0.10:6379> '//quit退出'
三、Redis数据库常用命令
3.1 redis-cli命令行工具
-
连接本地数据库
[root@localhost utils]# redis-cli 127.0.0.1:6379>
-
连接远程数据库
[root@localhost utils]# redis-cli -h 20.0.0.10 -p 6379 20.0.0.10:6379>
-
获取命令帮助
- help @ 获取中的命令列表
- help 获取某个命令的帮助
- help 获取可能帮助的主题列表
-
set 存放数据
-
get 获取数据
[root@localhost ~]# redis-cli 127.0.0.1:6379> set name zhangsan OK 127.0.0.1:6379> get name "zhangsan"
-
key相关命令
- keys ===>获取符合规则的键值列表
- exists ===>判断键值是否存在
- del ===>删除当前数据库的指定key
- type ===>获取key对应的value值类型
- rename(覆盖)/renamenx(不覆盖) ===>对已有的key进行重命名
- dbsize ===>查看当前数据库中key的数目
-
redis-benchmark测试工具
-
-h 指定服务器主机名
-
-p 指定服务器端口
-
-c 指定并发连接数
-
-n 指定请求数
-
-d 以字节的形式指定SET/GET值的数据大小
-
-q 强制退出Redis,仅显示query/sec值
-
向IP地址为20.0.0.10、端口为6379的Redis服务器发送100个并发连接与100000个请求测试性能
[root@localhost ~]# redis-benchmark -h 20.0.0.10 -p 6379 -c 100 -n 100000
-
测试存取大小为100字节的数据包的性能
[root@localhost ~]# redis-benchmark -h 20.0.0.10 -p 6379 -q -d 100
-
3.2 Redis多数据库操作
-
Redis支持多数据库,默认支持16个数据库,0-15命名
-
多数据库相互独立,互不干扰
-
多数据库常用命令
-
多数据库间切换
select [0-15] '//切换数据库'
-
多数据库间移动数据
move key db '//移动数据,源数据会删除'
-
清除数据库内数据
del key
-
3.3 设置hash结构
hset 对象名称 对象属性名称 值
127.0.0.1:6379> hset person name zhangsan
127.0.0.1:6379> hset person age 18
127.0.0.1:6379> hset person score 90
127.0.0.1:6379> keys *
1)"person"
127.0.0.1:6379> hget person name
"zhangsan"
四、Redis持久化
-
持久化概述
- Redis是运行在内存中,内存中的数据断电丢失
- 为了能够重用Redis数据,或者防止系统故障,需要将Redis中的数据写入到磁盘空间中,即持久化
-
持久化分类
- RDB方式: 创建快照的方式获取某一个时刻Redis中所有数据的副本
- AOF方式: 将执行的写命令写到文件的末尾,以日志的方式来记录数据的变化
4.1 RDB持久化
-
Redis的默认持久化方式
-
默认文件名dump.rdb
-
触发条件
- 在指定的时间间隔内,执行指定次数的写操作(配置文件控制)
- 执行save或者是bgsave(异步)命令
- 执行flushall命令,清空数据库所有数据
- 执行shutdown命令,保证服务器正常关闭且不丢失任何数据
-
优缺点
- 适合大规模的数据恢复
- 如果业务对数据完整性和一致性要求不高,RDB是很好的选择
- 数据的完整性和一致性不高
- 备份时占用内存
-
通过RDB文件恢复数据
- 将dump.rdb文件拷贝到redis的安装目录的bin目录下,重启redis服务即可
-
配置文件选项
[root@localhost ~]# vim /etc/redis/6379.conf ... save 900 1 '//900秒之内至少一次写操作' save 300 10 '//300秒之内至少发生20次写操作' save 60 10000 '//60秒之内发生至少10000次写操作' '//只要满足其一都会触发快照操作,注释所有的save项表示关闭RDB' dbfilename dump.rdb '//RDB文件名称' dir /var/lib/redis/6379 '//RDB文件路径' rdbcompression yes '//是否进行压缩'
4.2 AOF持久化
-
Redis默认不开启
-
弥补RDB的不足(数据的不一致性)
-
采用日志的形式来记录每个写操作,并追加到文件中
-
Redis重启会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作
-
根据AOF文件恢复数据
#配置文件选项 [root@localhost ~]# vim /etc/redis/6379.conf ... appendonly yes '//开启AOF持久化' appendfilename "appendonly.aof" '//AOF文件名称' #appendfsync always '//同步持久化,每次发生数据变化会立刻写入磁盘' appendfsync everysec '//默认推荐,每秒异步记录一次(默认值)' #appendfsync no '//不同步,交给操作系统决定如何同步' aof-load-truncated yes '//忽略最后一条可能存在问题的指令'
-
AOF的重写机制
- AOF的工作原理是将写操作追加到文件中,文件的冗余内容会越来越多
- 当AOF文件的大小超过所设定的阈值时,Redis就会对AOF文件的内容压缩
-
AOF重写的原理
- Redis会fork出一条新进程,读取内存中的数据(并没有读取旧文件),并重新写到一个临时文件中,最后替换旧的aof文件
-
AOF的重写配置
[root@localhost ~]# vim /etc/redis/6379.conf #在日志进行BGREWRITEAOF时,如果设置为yes表示新写操作不进行同步fsync,只是暂存在缓冲区里,避免造成磁盘IO操作冲突,等重写完成后在写入.Redis中默认为no no-appendfsync-on-rewrite no #当前AOF文件大小是上次日志重写时AOF文件大小两倍时,发生BGREWRITEAOF操作 auto-aof-rewrite-percentage 100 #当前AOF文件执行BGREWRITEAOF命令的最小值,避免刚开始启动Redis时由于文件尺寸较小导致频繁的BGREWRITEAOF auto-aof-rewrite-min-size 64mb
五、Redis性能管理
-
查看Redis内存使用
[root@localhost ~]# redis-cli 127.0.0.1:6379> info memory # Memory used_memory:853320 used_memory_human:833.32K '//内存使用总量' ... mem_fragmentation_ratio:13.60 '//内存碎片率' mem_fragmentation_bytes:10238712 mem_not_counted_for_evict:0 mem_replication_backlog:0 mem_clients_slaves:0 mem_clients_normal:49694 mem_aof_buffer:0 mem_allocator:jemalloc-5.1.0 ...
-
内存碎片率
- 操作系统分配的内存值used_memory_rss除以Redis使用的内存值used_memory计算得出
- 内存碎片是由操作低效的分配/回收物理内存导致的
- 不连续的物理内存分配
- 跟踪内存碎片率对理解Redis实例的资源性能是非常重要的
- 内存碎片率稍大于1是合理的,这个值表示内存碎片率比较低
- 内存碎片率超过1.5,说明Redis消耗了实际需要物理内存的150%,其中50%是内存碎片率
- 内存碎片率低于1的,说明Redis内存分配超过了物理内存,操作系统正在进行内存交换
-
内存使用率
- redis实例的内存使用率超过可用最大内存,操作系统将开始进行内存与swap空间交换
- 避免内存交换
- 针对缓存数据大小选择
- 尽可能的使用Hash数据结构
- 设置key的过期时间
-
回收key
-
保证合理分配redis有限的内存资源
-
当达到设置的最大阈值时,需选择一种key的回收策略
-
默认情况下回收策略是禁止删除
-
redis.conf配置文件中修改maxmemory-policy属性值
- volatile-lru ===>使用LRU算法从已设置过期时间的数据集合中淘汰数据
- volatile-ttl ===>从已设置过期时间的数据集合中挑选即将过期的数据淘汰
- volatile-random ===>从已设置过期时间的数据集合中随机挑选数据淘汰
- allkeys-lru ===>使用LRU算法从所有数据集合中淘汰数据
- allkeys-ransom ===>从数据集合中任意选择数据淘汰
- no-enviction ===>禁止淘汰数据
-
-