NoSQL之Redis配置与优化
1. Redis概述
1.1 数据库
●一个结构化的数据库,创建在关系模型基础上
●一般面向于记录
●包括
.Oracle、MySQL、SQL Server、Microsoft Access、DB2等
非关系型数据库
●除了主流的关系型数据库外的数据库,都认为是非关系型
●包括
.Redis、MongBD、Hbase、CouhDB等
1.2 Redis简介
●Redis基于内存运行并支持持久化
●采用Key-value(键值对)的存储形式
●优点
1.具有极高的数据读写速度
2.支持丰富的数据类型
3.支持数据的持久化
4.原子性
5.支持数据备份
1.3 Redis配置文件
配置参数(/etc/redis/6379.conf)
●bind:监听的主机地址
●port:端口
●daemonize yes:启用守护进程
●pidfile: 指定PID文件
●loglevel notice:日志级别
●logfile: 指定日志文件
1.4 redis-cli命令行工具
连接本地数据库
[root@localhost utils]# /usr/local/redis/bin/redis-cli
127.0.0.1:6379>
连接远程数据库
[root@localhost utils]# redis-cli -h 192.168.10.161 -p 6379192.168.10.161:6379>
获取命令帮助
help @<group>:获取<group的命令列表
help <command>:获取某个命令的帮助
help <tab>:获取可能帮助的主题列表
redis-cli命令行工具
set:存放数据
get:获取数据
1.5 key相关命令
●keys:获取符合规则的键值列表
●exists:判断键值是否存在
●del:删除当前数据库的指定key
●type:获取key对应的value值类型
●rename(覆盖) / renamenx(不覆盖):对已有的key进行重命名
●dbsize:查看当前数据库中key的数
1.6 redis-benchmark测试工具
●-h:指定服务器主机名
●-p︰指定服务器端口
●-c:指定并发连接数o
●-n:指定请求数
●-d:以字节的形式指定SET/GET值的数据大小
●-q:强制退出Redis,仅显示query/sec值
1.7 redis-benchmark测试工具
●向IP地址为192.168.10.161、端口为6379的Redis服务器发送100个并发连接与100000个请求测试性能
[root@localhost ~]# /usr/local/redis/bin/redis-benchmark -h 192.168.10.161-p 6379 -c 100 -n 10000o
●测试存取大小为100字节的数据包的性能
[root@localhost ~]# /usr/local/redis/bin/redis-benchmark -h 192.168.10.161-p 6379 -q-d 100
2. Redis多数据库操作
Redis支持多数据库,默认支持16个数据库,0-15命名多数据库相互独立,互不干扰
多数据库常用命令
●多数据库间切换
●多数据库间移动数据
●清除数据库内数据
2.1 安装redis
[root@localhost ~]# yum -y install gcc gcc-c++ make ##安装编译器
[root@localhost ~]# tar zxvf redis-5.0.7.tar.gz -C /opt ##解压软件到opt下面
[root@localhost redis-5.0.7]# make prefix=/usr/local/redis install ##编译 后面是指定路径
[root@localhost bin]# cd /opt/redis-5.0.7/utils/
[root@localhost utils]# ll
total 52
-rw-rw-r--. 1 root root 593 Nov 20 2019 build-static-symbols.tcl
-rw-rw-r--. 1 root root 1303 Nov 20 2019 cluster_fail_time.tcl
-rw-rw-r--. 1 root root 1098 Nov 20 2019 corrupt_rdb.c
drwxrwxr-x. 2 root root 60 Nov 20 2019 create-cluster
-rwxrwxr-x. 1 root root 2149 Nov 20 2019 generate-command-help.rb
drwxrwxr-x. 3 root root 31 Nov 20 2019 graphs
drwxrwxr-x. 2 root root 39 Nov 20 2019 hashtable
drwxrwxr-x. 2 root root 70 Nov 20 2019 hyperloglog
-rwxrwxr-x. 1 root root 9567 Nov 20 2019 install_server.sh
drwxrwxr-x. 2 root root 63 Nov 20 2019 lru
-rw-rw-r--. 1 root root 1277 Nov 20 2019 redis-copy.rb
-rwxrwxr-x. 1 root root 1352 Nov 20 2019 redis_init_script
-rwxrwxr-x. 1 root root 1047 Nov 20 2019 redis_init_script.tpl
-rw-rw-r--. 1 root root 1762 Nov 20 2019 redis-sha1.rb
drwxrwxr-x. 2 root root 135 Nov 20 2019 releasetools
-rwxrwxr-x. 1 root root 3787 Nov 20 2019 speed-regression.tcl
-rwxrwxr-x. 1 root root 693 Nov 20 2019 whatisdoing.sh
[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]# netstat -ntap | grep redis ##查看服务
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 20257/redis-server
[root@localhost utils]# redis-cli -h 1
2.2 测试服务
27.0.0.1 -p 6379 ###登录本地测试
127.0.0.1:6379> set name zhangsan
OK
127.0.0.1:6379> get name
"zhangsan"
[root@localhost utils]# redis-cli -h 20.0.0.16 -p 6379 ##登录ip地址报错,这是因为没有授权
Could not connect to Redis at 20.0.0.16:6379: Connection refused ##20.0.0.16:6379无法连接到Redis:连接拒绝
[root@localhost utils]# vi /etc/redis/6379.conf ##主配置文件
70 bind 127.0.0.1 20.0.0.16 ##加入授权ip
[root@localhost utils]# /etc/init.d/redis_6379 stop ##关闭redis服务
Stopping ...
Waiting for Redis to shutdown ...
Redis stopped
[root@localhost utils]# /etc/init.d/redis_6379 start ##开启redis服务
Starting Redis server...
[root@localhost utils]# /etc/init.d/redis_6379 restart ##重启redis服务
Stopping ...
Waiting for Redis to shutdown ...
Redis stopped
Starting Redis server...
[root@localhost utils]# /etc/init.d/redis_6379 status ##redis状态
Redis is running (20548)
[root@localhost utils]# vi /etc/redis/6379.conf
70 bind 127.0.0.1 20.0.0.16 ###监听地址
93 port 6379 ###端口号
137 daemonize yes ##开启守护进程
159 pidfile /var/run/redis_6379.pid ##pid文件
167 loglevel notice ##
172 logfile /var/log/redis_6379.log ##日志文件
[root@localhost utils]# redis-cli -h 20.0.0.16 -p 6379 ##通过20.0.0.16IP地址登录
20.0.0.16:6379> type name ##查看类型
string
3. Redis数据类型
Redis支持五种数据类型: string (字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集
3.1 String(字符串)
string是redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value.string 类型是二进制安全的。redis的string 可以包含任何数据。比如jpg图片或者序列化的对象。
string类型是Redis最基本的数据类型,string 类型的值最大能存储512MB.
示例:
[root@localhost utils]# redis-cli -h 20.0.0.16 -p 6379 ##通过20.0.0.16IP地址登录
20.0.0.16:6379> set name zhangsan
OK
20.0.0.16:6379> get name
"zhangsan"
3.2 Hash(哈希字典)
Redis hash是一个键值(key=>value)对集合。
Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。
每个hash可以存储2的32次方-1键值对。
作用场景:
键值对集合,即编程语言中的Map类型 适合存储对象,并且可以像数据库中update一个属性一样只修改某一项属性值
示例:
[root@localhost utils]# redis-cli -h 20.0.0.16 -p 6379 ##通过20.0.0.16IP地址登录
20.0.0.16:6379> HMSET stu name zhanger age 25 sex 女 ##一个对象当中包含多个key和vlaue
OK
20.0.0.16:6379> hget stu name ##查看name
"zhanger"
20.0.0.16:6379> hget stu age ##查看age
"25"
20.0.0.16:6379> hget stu sex ##查看性别,出现乱码
"\xe5\xa5\xb3"
解决方案:[root@localhost utils]# redis-cli -h 20.0.0.16 -p 6379 --raw ##--raw 解析中文字符集
20.0.0.16:6379> hget stu sex
女
3.3 List(列表)
Redis列表是简单的字符串列表,按照插入顺序排序,可以重复。可以添加一个元素到列表的头部(左边))或者尾部(右边),列表最多可存储2的32次方-1元素。
作用场景:
增删快,提供了操作某一段元素的API 1,最新消息排行等功能(比如朋友圈的时间线)⒉,消息队列
例子:
20.0.0.16:6379> LPUSH hobby play ##创建key值hpbby ,value值play
1
20.0.0.16:6379> LPUSH hobby read spot
3 ##代表的hobby里面的value数量
20.0.0.16:6379> LRANGE hobby 0 10 ###0 到 10 从右往左取值
spot
read
play
20.0.0.16:6379> LRANGE hobby 0 2 ## 0 到 2
spot
read
play
20.0.0.16:6379> LPUSH hobby read ###一个列表之中可以存一样的数据
4
20.0.0.16:6379> LRANGE hobby 0 3
read
spot
read
play
20.0.0.16:6379> LRANGE hobby 3 3
play
3.4 set(集合)
Redis的Set是string类型的无序集合。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)
作用场景:
1、共同好友2、利用唯一性,统计访问网站的所有独立ip 3、好友推荐时,根据tag求交集,大于某个阈值就可以推荐
sadd命令
添加一个string元素到key对应的set集合中,成功返回1,如果元素已经在集合中返回0。
示例:
20.0.0.16:6379> SADD color red green yellow blue
4
20.0.0.16:6379> SMEMBERS color ##查看所有
blue
yellow
red
green
20.0.0.16:6379> SADD color red ###返回为0代表没有存入
0
集合里面不能有重复数据,数据是无序的,用smemebers查看
20.0.0.16:6379> keys * ##查看所有的key
color
name
hobby
stu
3.5 zset(sorted set:有序集合)
Redis zset和set一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
zset的成员是唯一的,但分数(score)却可以重复。
作用场景:
将Set中的元素增加一个权重参数score,元素按score有序排列
数据插入集合时,已经进行天然排序
1、排行榜2、带权重的消息队列
zadd命令
添加元素到集合,元素在集合中存在则更新对应score
示例:
[root@localhost utils]# redis-cli -h 20.0.0.16 -p 6379 --raw ##--raw 解析中文字符集
20.0.0.16:6379> del color ##删除key
1
20.0.0.16:6379> ZADD color 1 red
1
20.0.0.16:6379> ZADD color 1 blue
1
20.0.0.16:6379> ZADD color 2 yellow
1
20.0.0.16:6379> ZADD color 3 green
1
20.0.0.16:6379> ZRANGEBYSCORE color 1 10
blue
red
yellow
green
20.0.0.16:6379> ZRANGEBYSCORE color 1 1
blue
red
20.0.0.16:6379> ZRANGEBYSCORE color 2 2
yellow
20.0.0.16:6379> ZRANGEBYSCORE color 2 3
yellow
green
有序集合,分数去调
4.多数据库概念
Redis支持多个数据库,并且每个数据库的数据是隔离的不能共享,并且基于单机才有,如果是集群就没有数据库的概悉。
Redis是一个字典结构的存储服务器,而实际上一个Redis实例提供了多个用来存储数据的字典,
客户端可以指定将数据存储在哪个字典中。这与我们熟知的在一个关系数据库实例中可以创建多个数据库类似,所以可以将其中的每个字典都理解成一个独立的数据库。
每个数据库对外都是一个从O开始的递增数字命名,Redis默认支持16个数据库(可以通过配置文件支持更多,无上限),可以通过配置databases来修改这一数字。客户端与Redis建立连接后会自动选择0号数据库,
不过可以随时使用SELECT命令更换数据库,如要选择1号数据库:
4.1 移动数据和切换数据库
[root@localhost utils]# redis-cli -h 20.0.0.16 -p 6379 --raw ##--raw 解析中文字符集
20.0.0.16:6379> move color 1 ##移动数据color到数据库2中
1
20.0.0.16:6379> SELECT 1 ##到数据库2中 默认数据库16个(0-15)
OK
20.0.0.16:6379[1]> keys * ##查看所有key
color
20.0.0.16:6379[1]> SET name zhang ##创建键值对
OK
20.0.0.16:6379[1]> get name ##查看name
zhang
20.0.0.16:6379[1]> rename name names ##改名字
OK
20.0.0.16:6379[1]> get name ##查看name,没有数据
20.0.0.16:6379[1]> get names ##查看names,有zhang数据
zhang
4.2 清空所有数据库数据
20.0.0.16:6379[1]> FLUSHALL ##清空所有
OK
20.0.0.16:6379[1]> SELECT 0 ##查看数据库1中的数据
OK
20.0.0.16:6379> KEYS *
注意:
Redis不支持自定义数据库的名字,每个数据库都以编号命名,开发者必须自己记录哪些数据库存储了哪些数据。i另外Redis也不支持为每个数据库设置不同的访问密码,所以一个客户端要么可以访问全部数据库,
要么连一个数据库也没有权限访问。最重要的一点是多个数据库之间并不是完全隔离的,
比如FLUSHALL命令可以清空一个Redis实例中所有数据库中的数据。
综上所述,这些数据库更像是一种命名空间,而不适宜存储不同应用程序的数据。
作用场景:
可以使用0号数据库存储某个应用生产环境中的数据,使用1号数据库存储测试环境中的数据,
但不适宜使用0号数据库存储A应用的数据而使用1号数据库B应用的数据,不同的应用应该使用不同的Redis实例存储数据。
由于Redis非常轻量级,一个空Redis实例占用的内存只有1M左右,所以不用担心多个Redis实例会额外占用很多内存。
4.3 key常规管理
4.3.1 验证key是否存在 exists
20.0.0.16:6379> set name zhangdan
OK
20.0.0.16:6379> EXISTS name
1
20.0.0.16:6379> EXISTS names
0
4.3.2 重命名 rename
变key值不变里面内容
20.0.0.16:6379> rename name names
OK
20.0.0.16:6379> get names
zhangdan
4.3.3 设置超时时间 pexpire
(单位:毫秒)一秒钟是1000毫秒
20.0.0.16:6379> set name zhangdan
OK
20.0.0.16:6379> PTTL name ##查看失效时间 -1 永不超时
-1
20.0.0.16:6379> PEXPIRE name 30000 ##设置超时时间30秒
1
20.0.0.16:6379> PTTL name
28762
20.0.0.16:6379> PERSIST name ###恢复永不超时
1
20.0.0.16:6379> PTTL name
-1
4.3.4 随机查看key
20.0.0.16:6379> mset age 52 sex boy score 88
OK
20.0.0.16:6379> KEYS *
sex
age
name
score
20.0.0.16:6379> RANDOMKEY
name
20.0.0.16:6379> RANDOMKEY
name
20.0.0.16:6379> RANDOMKEY
score
20.0.0.16:6379> RANDOMKEY
score
5. redis持久化
5.1 持久化概述
● Redis是运行在内存中,内存中的数据断电丢失
●为了能够重用Redis数据,或者防止系统故障,需要将Redis中的数据写入到磁盘空间中,即持久化
持久化分类
●RDB方式:创建快照的方式获取某一时刻Redis中所有数据的副本
●AOF方式:将执行的写命令写到文件的末尾,以日志的方式来记录数据的变化
注意点:快照时间点,RDB不是连续的,是基于一个时刻,如果还没有到下一次快照时间,中间停电了,可能造成部分数据丢失
两种方式:相辅相成的
5.2 默认文件名dump.rdb
5.3 触发条件
●在指定的时间间隔内,执行指定次数的写操作(配置文件控制)
●执行save或者是bgsave(异步)命令
●执行flushall命令,清空数据库所有数据
●执行shutdown命令,保证服务器正常关闭且不丢失任何数据
5.4 优缺点
●适合大规模的数据恢复
●如果业务对数据完整性和一致性要求不高,RDB是很好的选择
●数据的完整性和一致性不高
●备份时占用内存
5.5 通过RDB文件恢复数据
●将dump.rdb文件拷贝到redis的安装目录的bin目录下,重启redis服务即可
配置文件选项
●Redis默认不开启
●弥补RDB的不足(数据的不一致性)
●采用日志的形式来记录每个写操作,并追加到文件中
●Redis重启会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作
5.6 根据AOF文件恢复数据
●将appendonly.aof 文件拷贝到Redis的安装目录的bin目录下,重启Redis服务即可
配置文件选项
5.6.1 AOF的重写机制
●AOF的工作原理是将写操作追加到文件中,文件的冗余内容会越来越多
●当AOF文件的大小超过所设定的阈值时,Redis就会对AOF文件的内容压缩
AOF重写的原理
●Redis会fork出一条新进程,读取内存中的数据(并没有读取旧文件),并重新写到一个临时文件中,最后替换旧的aof文件
5.6.1 AOF的的重写配置
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命令的最小值,避免刚开始启动Reids时由于文件尺寸较小导致频繁的BGREWRITEAOF
auto-aof-rewrite-min-size 64mb
5.7 Redis性能管理
5.7.1 查看Redis内存使用
[root@localhost bin]# redis-cli
127.0.0.1:6379> info memory
# Memory
used_memory:2594360
used_memory_human:2.47M ##内存使用总量
used_memory_rss:14864384
used_memory_rss_human:14.18M
used_memory_peak:2635264
used_memory_peak_human:2.51M
used_memory_peak_perc:98.45%
used_memory_overhead:2565042
used_memory_startup:1449664
used_memory_dataset:29318
used_memory_dataset_perc:2.56%
allocator_allocated:3041488
allocator_active:3358720
allocator_resident:10420224
total_system_memory:3958075392
total_system_memory_human:3.69G
used_memory_lua:37888
used_memory_lua_human:37.00K
used_memory_scripts:0
used_memory_scripts_human:0B
number_of_cached_scripts:0
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
allocator_frag_ratio:1.10
allocator_frag_bytes:317232
allocator_rss_ratio:3.10
allocator_rss_bytes:7061504
rss_overhead_ratio:1.43
rss_overhead_bytes:4444160
mem_fragmentation_ratio:5.82 ##内存碎片率
mem_fragmentation_bytes:12311048
mem_not_counted_for_evict:114
mem_replication_backlog:1048576
mem_clients_slaves:16922
mem_clients_normal:49694
mem_aof_buffer:114
mem_allocator:jemalloc-5.1.0
active_defrag_running:0
lazyfree_pending_objects:0
5.7.2 内存碎片率
●操系统分配的内存值used_memory_rss除以Redis使用的内存值used_memory计算得出
●内存碎片是由操作系统低效的分配/回收物理内存导致的不连续的物理内存分配
●跟踪内存碎片率对理解Redis实例的资源性能是非常重要的
●内存碎片率稍大于1是合理的,这个值表示内存碎片率比较低
●内存碎片率超过1.5,说明Redis消耗了实际需要物理内存的150%,其中50%是内存碎片率
●内存碎片率低于1的,说明Redis内存分配超出了物理内存,操作系统正在进行内存交换
5.7.3 内存使用率
●redis实例的内存使用率超过可用最大内存,操作系统将开始进行内存与swap空间交换
避免内存交换
●针对缓存数据大小选择
●尽可能的使用Hash数据结构
●设置key的过期时间
cat /proc /meminfo 物理内存
cat /proc /cpuinfo cpu信息
uname -r 内核版本
5.7.4 回收key
●保证合理分配redis有限的内存资源
●当达到设置的最大阀值时,需选择—种key的回收策略
默认情况下回收策略是禁止删除
redis.conf配置文件中修改maxmemory-policy属性值
volatile-lru:使用LRU算法从已设置过期时间的数据集合中淘汰数据.
volatile-ttl:从已设置过期时间的数据集合中挑选即将过期的数据淘汰
volatile-random:从已设置过期时间的数据集合中随机挑选数据淘汰
allkeys-Iru:使用LRU算法从所有数据集合中淘汰数据
allkeys-random:从数据集合中任意选择数据淘汰
no-enviction:禁止淘汰数据
建议使用volatile-lru