Redis配置与优化
存储数据类型分类
结构化数据:可以通过二维表格形式表述这个数据
非结构化数据:不方便以二维表格形式表述的这种类型的数据
根据不同种存储数据类型分类分成两种不同类型的数据库
- sql结构化数据库:里面存储的数据类型是结构化数据。别称称为关系型数据库
- nosql非结构化数据库:里面存储的数据类型是非结构化数据。别称称为非关系型数据库
关系型数据库与非关系型数据库
关系型数据库
- 一个结构化的数据库,创建在关系模型基础上
- 一般面向于记录
- 包括
- Oracle、MySQL、SQL Server、Microsoft Access、DB2
非关系型数据库
- 除了主流的关系型数据库外的数据库,都认为是非关系型
- 包括
- Redis、MongBD、Hbase、CouhDB等
非关系型数据库产生背景
- High performance———对数据库高并发读写需求
- Huge Storage———对海量数据高效存储与访问需求
- High Scalability && High Availability——对数据库高可扩展性与高可用性需求
Redis简介
- Redis基于内存运行并支持持久化
- 采用key-value(键值对)的存储形式
- 优点
- 具有极高的数据读写速度
- 支持丰富的数据类型
- 支持数据的持久化
- 原子性
- 支持数据备份
Redis与Memcached的区别
- | Memcached | Redis |
---|---|---|
类型 | Key-value数据库 | Key-value数据库 |
过期策略 | 支持 | 支持 |
数据类型 | 单一数据类型 | 五大数据类型 |
持久化 | 不支持 | 支持 |
主从复制 | 不支持 | 支持 |
虚拟内存 | 不支持 | 支持 |
Redis支持五种数据类型:
- string(字符串)
- string 是 redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value
- string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象
- string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB
- hash(哈希)
- Redis hash 是一个键值(key=>value)对集合
- Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象
- list(列表)
- Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)
- set(集合)
- Redis 的 Set 是 string 类型的无序集合
- 集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)
- zset(sorted set:有序集合)
- Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员
- 不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序
- zset的成员是唯一的,但分数(score)却可以重复
各数据类型应用场景
类型 | 简介 | 特性 | 场景 |
---|---|---|---|
String(字符串) | 二进制安全 | 可以包含任何数据,比如jpg图片或者序列化的对象,一个键最大能存储512M | - |
Hash(字典) | 键值对集合,即编程语言中的Map类型 | 适合存储对象,并且可以像数据库中update一个属性一样只修改某一项属性值(Memcached中需要取出整个字符串反序列化成对象修改完再序列化存回去) | 存储、读取、修改用户属性 |
List(列表) | 链表(双向链表) | 增删快,提供了操作某一段元素的API | 1、最新消息排行等功能(比如朋友圈的时间线) ;2、消息队列 |
Set(集合) | 哈希表实现,元素不重复 | 添加、删除,查找的复杂度都是O(1) 2、为集合提供了求交集、并集、差集等操作 | 1、共同好友 ;2、利用唯一性,统计访问网站的所有独立ip; 3、好友推荐时,根据tag求交集,大于某个阈值就可以推荐 |
Sorted | 将Set中的元素增加 | 数据插入集合时,已经进行天然排序 | 1、排行榜 ;2、带权重的消息队列 |
redis部署
添加安装包
解压缩
[root@server3 ~]# tar zxvf redis-5.0.4.tar.gz
配置文件
[root@server3 ~]# cd redis-5.0.4/
[root@server3 redis-5.0.4]# make # 进行配置
[root@server3 redis-5.0.4]# make PREFIX=/usr/local/redis install #更改安装路径可以用make PREFIX=安装路径 install
[root@server3 redis-5.0.4]# ln -s /usr/local/redis/bin/* /usr/local/bin #创建链接
[root@server3 redis-5.0.4]# cd /usr/local/redis/bin/ #查看命令
[root@server3 bin]# ll
[root@server3 redis-5.0.4]# cd utils/ #查看安装脚本
[root@server3 utils]# ls -lh
[root@server3 utils]#./install_server.sh
查看Redis运行状态
[root@server3 ~]# /etc/init.d/redis_6379 stop #停止Redis服务
[root@server3 ~]# /etc/init.d/redis_6379 start #启动Redis服务
[root@server3 ~]# netstat -anpt | grep redis #查看端口
添加监听端口
[root@server3 ~]# vi /etc/redis/6379.conf
修改:
bind 127.0.0.1 20.0.0.13 #把允许登录的地址加到配置文件的bind后面
[root@server3 ~]# /etc/init.d/redis_6379 restart
[root@server3 ~]# redis-cli -h 20.0.0.13 -p 6379 #连接redis数据库
测试五种数据类型
String(字符串)
[root@server3 ~]# redis-cli -h 20.0.0.13 -p 6379
20.0.0.13:6379> set a 14 # 设置a的值为14
OK
20.0.0.13:6379> get a # 获取a值 输出返回14
"14"
20.0.0.13:6379> type a # 查看a的状态类型
string
20.0.0.13:6379> incr a # 自增长 +1
(integer) 15
20.0.0.13:6379> get a # 获取a值的为15
"15"
20.0.0.13:6379> decr a # 自减 -1
(integer) 14
20.0.0.13:6379> get a # 获取a值的为14
"14"
20.0.0.13:6379> incrby a 5 # 设置增值为5
(integer) 19
20.0.0.13:6379> decrby a 6 # 设置降值为6
(integer) 13
Hash(哈希)
20.0.0.13:6379> hset hash1 key1 a #设置字段key1为a
(integer) 1
20.0.0.13:6379> hset hash1 key1 aa #设置字段key1为aa覆盖
(integer) 0
20.0.0.13:6379> hset hash1 key2 aa #设置字段key2为aa
(integer) 1
20.0.0.13:6379> hset hash1 key3 aaa #设置字段key3为aaa
(integer) 1
20.0.0.13:6379> hset hash1 field1 a1 field2 a2
(integer) 2 #存入多个字段,分别为field1为a1,field2为a2
20.0.0.13:6379> hget hash1 key1 #获取字段key1为aa
"aa"
20.0.0.13:6379> hget hash1 key2 #获取字段key2为aa
"aa"
20.0.0.13:6379> hget hash1 key3 #获取字段key3为aaa
"aaa"
20.0.0.13:6379> hmget hash1 field1 field2
1) "a1"
2) "a2"
20.0.0.13:6379> hmget hash1 key1 key2 key3 field1 field2
1) "aa"
2) "aa"
3) "aaa"
4) "a1"
5) "a2"
List(列表)
20.0.0.13:6379> lpush list1 7 8 9 10 11
(integer) 5
20.0.0.13:6379> llen list1
(integer) 5
20.0.0.13:6379> lpop list1
"11"
20.0.0.13:6379> llen list1
(integer) 4
20.0.0.13:6379> lrange list1 0 5
1) "10"
2) "9"
3) "8"
4) "7"
Set(集合)
20.0.0.13:6379> sadd set1 10
(integer) 1
20.0.0.13:6379> sadd set1 20
(integer) 1
20.0.0.13:6379> sadd set1 30
(integer) 1
20.0.0.13:6379> sadd set1 40
(integer) 1
20.0.0.13:6379> scard set1
(integer) 4
20.0.0.13:6379> sismember set1 50
(integer) 0
20.0.0.13:6379> sismember set1 10
(integer) 1
20.0.0.13:6379> sismember set1 20
(integer) 1
20.0.0.13:6379> sismember set1 30
(integer) 1
20.0.0.13:6379> sismember set1 40
(integer) 1
zset(sorted set:有序集合)
20.0.0.13:6379> Zadd zset1 1.1 a1
(integer) 1
20.0.0.13:6379> Zadd zset1 1.1 a2
(integer) 1
20.0.0.13:6379> Zadd zset1 2.1 b1
(integer) 1
20.0.0.13:6379> Zadd zset1 2.1 b2
(integer) 1
20.0.0.13:6379> Zadd zset1 3.1 c1
(integer) 1
20.0.0.13:6379> Zrangebyscore zset1 0 5
1) "a1"
2) "a2"
3) "b1"
4) "b2"
5) "c1"
20.0.0.13:6379> Zrange zset1 0 5 withscores
1) "a1"
2) "1.1000000000000001"
3) "a2"
4) "1.1000000000000001"
5) "b1"
6) "2.1000000000000001"
7) "b2"
8) "2.1000000000000001"
9) "c1"
10) "3.1000000000000001"
Redis配置文件
配置参数
/etc/redis/6379.conf
- bind:监听的主机地址
- port:端口
- daemonize yes:启用守护进程
- pidfile:指定PID文件
- loglevel notice:日志级别
- logfile:指定日志文件
Redis数据库常用命令
redis-cli命令行工具
-
连接本地数据库
[root@localhost utils]# /usr/local/redis/bin/redis-cli127.0.0.1:6379> -
连接远程数据库
[root@localhost utils]# redis-cli -h 192.168.10.161 -p 6379192.168.10.161:6379>
Redis 命令工具
- redis-server #用于启动Redis的工具
- redis-benchmark #用于检测Redis 在本机的运行效率
- redis-check-aof #修复AOF持久化文件
- redis-check-rdb #修复RDB 持久化文件
- redis-cli ##是Redis命令行工具
- redis-setinel //是哨兵模式启动的工具
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:通过管道传输请求
- -q:强制退出redis。仅显示query/sec值
- -csv:以cSV格式输出
- -l:生成循环,永久执行测试
- -t:仅运行以逗号分隔的测试命令列表
- -I:idle模式。仅打开N个idle连接并等待
key相关命令
- keys:获取符合规则的键值列表
- exists:判断键值是否存在
- del:删除当前数据库的指定key
- type:获取key对应的value值类型
- rename(覆盖) l renamenx(不覆盖):对已有
- key进行重命名
- dbsize:查看当前数据库中key的数目
Redis多数据库操作
-
Redis支持多数据库,默认支持16个数据库,0-15命名
-
多数据库相互独立,互不干扰
-
多数据库常用命令
多数据库间切换- Redis支持多数据库,Redis在没有任何改动的情况下默认包含16个数据库,数据库名称是用数字0-15来依次命名的。使用’Select命令可以进行’Redis的多数据库之间的切换,命令格式为selectindex,其中index表示数据库的序号。而使用redis-cli连接Redis数据库后,默认使用的是序号为O的数据库。
多数据库间移动数据
清除数据库内数据
- Redis数据库的整库数据删除主要分为两个部分:清空当前数据库数据,使用FLUSHDB
- 命令实现;清空所有数据库的数据,使用FLUSHALL命令实现。但是,数据清空操作比较危险,生产环境下一般不建议使用
Redis持久化
持久化概述
- Redis是运行在内存中,内存中的数据断电丢失
- 为了能够重用Redis数据,或者防止系统故障,需要将Redis中的数据写入到磁盘空间中,即持久化
持久化分类
- ROB方式:创建快照的方式获取某一时刻Redis中所有数据的副本
- AOF方式:将执行的写命令写到文件的末尾,以日志的方式来记录数据的变化
ROB与AOF的区别
- RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储
- AOF持久化日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录
ROB与AOF的优缺点
RDB的优势:
- 一旦采用该方式,那么你的整个Redis数据库将只包含一个文件,这对于文件备份而言是非常完美的。比如,你可能打算每个小时归档一次最近24小时的数据,同时还要每天归档一次最近30天的数据。通过这样的备份策略,一旦系统出现灾难性故障,我们可以非常容易的进行恢复
- 对于灾难恢复而言,RDB是非常不错的选择。因为我们可以非常轻松的将一个单独的文件压缩后再转移到其它存储介质上。
- 性能最大化。对于Redis的服务进程而言,在开始持久化时,它唯一需要做的只是fork出子进程,之后再由子进程完成这些持久化的工作,这样就可以极大的避免服务进程执行IO操作了
- 相比于AOF机制,如果数据集很大,RDB的启动效率会更高
AOF的优势
- 该机制可以带来更高的数据安全性,即数据持久性。Redis中提供了3中同步策略即每秒同步、每修改同步和不同步。事实上,每秒同步也是异步完成的,其效率也是非常高的,所差的是一旦系统出现宕机现象,那么这一秒钟之内修改的数据将会丢失。而每修改同步,我们可以将其视为同步持久化,即每次发生的数据变化都会被立即记录到磁盘中。可以预见,这种方式在效率上是最低的。至于无同步,无需多言,我想大家都能正确的理解它
- 由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容。然而如果我们本次操作只是写入了一半数据就出现了系统崩溃问题,不用担心,在Redis下一次启动之前,我们可以通过redis-check-aof工具来帮助我们解决数据一致性的问题
- 如果日志过大,Redis可以自动启用rewrite机制。即Redis以append模式不断的将修改数据写入到老的磁盘文件中,同时Redis还会创建一个新的文件用于记录此期间有哪些修改命令被执行。因此在进行rewrite切换时可以更好的保证数据安全性
- AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。事实上,我们也可以通过该文件完成数据的重建
RDB的劣势
- 如果你想保证数据的高可用性,即最大限度的避免数据丢失,那么RDB将不是一个很好的选择。因为系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失
- 由于RDB是通过fork子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟
AOF的劣势
- 对于相同数量的数据集而言,AOF文件通常要大于RDB文件。RDB 在恢复大数据集时的速度比 AOF的恢复速度要快
- 根据同步策略的不同,AOF在运行效率上往往会慢于RDB。总之,每秒同步策略的效率是比较高的,同步禁用策略的效率和RDB一样高效
RDB持久化
- Redis的默认持久化方式
- 默认文件名dump.rdb
- 触发条件
- 在指定的时间间隔内,执行指定次数的写操作(配置文件控制)
- 执行save或者是bgsave(异步)命令
- 执行flushall命令,清空数据库所有数据
- 执行shutdown命令,保证服务器正常关闭且不丢失任何数据
AOF持久化
- Redis默认不开启
- 弥补RDB的不足(数据的不一致性)
- 采用日志的形式来记录每个写操作,并追加到文件中
- Redis重启会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作
AOF的重写机制
- AOF的工作原理是将写操作追加到文件中,文件的冗余内容会越来越多
- 当AOF文件的大小超过所设定的阈值时,Redis就会对AOF文件的内容压缩
AOF重写的原理
Redis会fork出一条新进程,读取内存中的数据(开没有读取旧文件),并重新写到一个临时文件中,最后替换旧的aof文件
Redis性能管理
内存碎片率
- 操系统分配的内存值used_memory_rss除以Redis使用的内存值used_memory计算得出
- 内存碎片是由操作系统低效的分配/回收物理内存导致的
- 不连续的物理内存分配
- 跟踪内存碎片率对理解Redis实例的资源性能是非常重要的
- 内存碎片率稍大于1是合理的,这个值表示内存碎片率比较低
- 内存碎片率超过1.5,说明Redis消耗了实际需要物理内存的150%,其中50%是内存碎片率
- 内存碎片率低于1的,说明Redis内存分配超出了物理内存,操作系统正在进行内存交换
25/30
内存使用率
- redis实例的内存使用率超过可用最大内存,操作系统将开始进行内存与swap空间交换
- 避免内存交换
- 针对缓存数据大小选择
- 尽可能的使用Hash数据结构
- 设置key的过期时间
回收key
- 保证合理分配redis有限的内存资源
- 当达到设置的最人内1心u全默认情况下回收策略
- 默认情况下回收策略是禁止删除
- redis.conf配置文件中修改maxmemory-policy属性值
- volatile-lru:使曳LRU算法从已设置过期时间的数据集合中淘汰数据.
- volatile-ttl:从已设置过期时间的数据集合中挑选即将过期的数据淘汰
- volatile-random:从已设置过期时间的数据集合中随机挑选数据淘汰
- allkeys-Iru:使用LRU算法从所有数据集合中淘汰数据
- allkeys-random:从数据集合中任意选择数据淘汰. no-· · enviction:禁止淘汰数据