Redis入门,看这一篇就够了
摘要
在Web应用发展的初期,那时关系型数据库受到了较为广泛的关注和应用,原因是因为那时候Web站点基本上访问和并发不高、交互也较少。而在后来,随着访问量的提升,使用关系型数据库的Web站点多多少少都开始在性能上出现了一些瓶颈,而瓶颈的源头一般是在磁盘的I/O上。而随着互联网技术的进一步发展,各种类型的应用层出不穷,这导致在当今云计算、大数据盛行的时代,对性能有了更多的需求,主要体现在以下四个方面:
①低延迟的读写速度:应用快速地反应能极大地提升用户的满意度
②支撑海量的数据和流量:对于搜索这样大型应用而言,需要利用PB级别的数据和能应对百万级的流量
③大规模集群的管理:系统管理员希望分布式应用能更简单的部署和管理
④庞大运营成本的考量:IT部门希望在硬件成本、软件成本和人力成本能够有大幅度地降低
为了克服这一问题,NoSQL应运而生,它同时具备了高性能、可扩展性强、高可用等优点,受到广泛开发人员的青睐。
一、关系型数据库与非关系型数据库
1.1、关系型数据库
1.1.1、一个结构化的数据库,创建再关系型基础上
1.1.2、一般面向于记录
1.1.3、包括:Oracle、MySQL、SQL Server、Microsoft Access、DB2等
1.2、非关系型数据库
1.2.1、除了主流的关系型数据库外的数据库,都认为是非关系型
1.2.2、包括:Redis、MongoDB、Hbase、CouhDB等
1.3、非关系型数据库产生背景
1.3.1、High performance——对数据库高并发读写需求
1.3.2、Huge Storage——对海量数据高效存储与访问需求
1.3.3、High Scalability && High Availability——对数据库高可扩展性与高可用性需求
二、Redis是什么
2.1、Redis是现在最受欢迎的NoSQL数据库之一,Redis是一个使用ANSIC编写的开源、包含多种数据结构、支持网络、基于内存、可选持久性的键值对存储数据库,其具备如下特性:
2.1.1、基于内存运行,性能高效
2.1.2、支持分布式,理论上可以无限扩展
2.1.3、key-value存储系统
2.1.4、开源的使用ANSIC语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API
2.2、相比于其他数据库类型,Redis具备的特点是:
2.2.1、C/S通讯模型
2.2.2、单进程单线程模型
2.2.3、丰富的数据类型
2.2.4、操作具有原子性
2.2.5、持久化
2.2.6、高并发读写
2.2.7、支持lua脚本
2.3、哪些大厂在使用Redis?
2.3.1、微博
2.3.2、阿里巴巴
2.3.3、百度
2.3.4、美团
2.3.5、搜狐等
三、Redis的数据类型及主要特性
Redis提供的数据类型主要分为5种自有类型和一种自定义类型,这5种自有类型包括:String类型、哈希类型、列表类型、集合类型和有序集合类型。
3.1、String类型:
它是一个二进制安全的字符串,意味着它不仅能够存储字符串、还能存储图片、视频等多种类型, 最大长度支持512M。
对每种数据类型,Redis都提供了丰富的操作命令,如:
①GET/MGET
②SET/SETEX/MSET/MSETNX
③INCR/DECR
④GETSET
⑤DEL
3.2、哈希类型
该类型是由field和关联的value组成的map。其中,field和value都是字符串类型的。Redis是一个键值的集合。每个hash可以存储2的32次方-1个键值对
Hash的操作命令如下:
①HGET/HMGET/HGETALL
②HSET/HMSET/HSETNX
③HEXISTS/HLEN
④HKEYS/HDEL
⑤HVALS
3.3、列表类型
该类型是一个插入顺序排序、可以重复的字符串元素集合, 基于双链表实现。可以添加一个元素到列表的头部(左边)或者尾部,列表最多可存储2的32次方-1个元素
List的操作命令如下:
①LPUSH/LPUSHX/LPOP/RPUSH/RPUSHX/RPOP/LINSERT/LSET
②LINDEX/LRANGE
③LLEN/LTRIM
3.4、集合类型
Set类型是一种无顺序集合, 它和List类型最大的区别是:集合中的元素没有顺序, 且元素是唯一的。
Set类型的底层是通过哈希表实现的,其操作命令为:
①SADD/SPOP/SMOVE/SCARD
②SINTER/SDIFF/SDIFFSTORE/SUNION
Set类型主要应用于:在某些场景,如社交场景中,通过交集、并集和差集运算,通过Set类型可以非常方便地查找共同好友、共同关注和共同偏好等社交关系。
3.5、有序集合类型
ZSet是一种有序集合类型,每个元素都会关联一个double类型的分数权值,通过这个权值来为集合中的成员进行从小到大的排序。与Set类型一样,其底层也是通过哈希表实现的。
ZSet命令:
①ZADD/ZPOP/ZMOVE/ZCARD/ZCOUNT
②ZINTER/ZDIFF/ZDIFFSTORE/ZUNION
四、Redis配置文件
4.1、配置参数(/etc/redis/6379.conf)
①bind:监听的主机地址
②port:端口
③daemonize yes:启用守护进程
④pidfile:指定PID文件
⑤loglevel notice:日志级别
⑥logfile:指定日志文件
4.2、key相关命令
①keys:获取符合规则的键值列表
②exists:判断键值是否存在
③del:删除当前数据库的指定key
④type:获取key对应的value值类型
⑤rename(覆盖)/renamenx(不覆盖):重命名
⑥dbsize:查看当前数据库中key的数目
4.3、redis-benchmark测试工具
① -h:指定服务器的主机名
② -p:指定服务器端口
③ -c:指定并发连接数
④ -n:指定请求数
⑤ -d:以字节的形式指定SET/GET值的数据大小
⑥ -q:强制退出Redis,仅显示query/sec值
五、Redis安装部署
5.1、操作步骤
解压软件包—→make && make install—→设置Redis相关配置文件—→查看运行状态
5.2、编译安装Redis
1 [root@server1 ~]# tar zxf redis-5.0.7.tar.gz
2 [root@server1 ~]# cd redis-5.0.7/
3 [root@server1 redis-5.0.7]# make -j2
4 [root@server1 redis-5.0.7]# make PREFIX=/usr/local/redis install
5 [root@server1 redis-5.0.7]# ln -s /usr/local/redis/bin/* /usr/local/bin #将redis的所有命令拷贝到/usr/local/bin目录下,可以更便捷的使用
5.3、设置Redis相关配置文件
1 [root@server1 ~]# cd redis-5.0.7/
2 [root@server1 redis-5.0.7]# cd utils/
3 [root@server1 utils]# ./install_server.sh #执行安装服务脚本
4 Welcome to the redis service installer
5 This script will help you easily set up a running redis server
6
7 Please select the redis port for this instance: [6379] #确定端口号
8 Selecting default: 6379
9 Please select the redis config file name [/etc/redis/6379.conf] #redis配置文件
10 Selected default - /etc/redis/6379.conf
11 Please select the redis log file name [/var/log/redis_6379.log] #日志文件
12 Selected default - /var/log/redis_6379.log
13 Please select the data directory for this instance [/var/lib/redis/6379] #数据存放目录
14 Selected default - /var/lib/redis/6379
15 Please select the redis executable path [/usr/local/bin/redis-server]
16 Selected config:
17 Port : 6379
18 Config file : /etc/redis/6379.conf
19 Log file : /var/log/redis_6379.log
20 Data dir : /var/lib/redis/6379
21 Executable : /usr/local/bin/redis-server
22 Cli Executable : /usr/local/bin/redis-cli
23 Is this ok? Then press ENTER to go on or Ctrl-C to abort.
24 Copied /tmp/6379.conf => /etc/init.d/redis_6379
25 Installing service...
26 Successfully added to chkconfig!
27 Successfully added to runlevels 345!
28 Starting Redis server...
29 Installation successful!
5.4、登录redis
1 [root@server1 src]# redis-cli -h 127.0.0.1 -p 6379
2 127.0.0.1:6379>
5.5、数据类型
5.5.1、string(字符串)是redis最基本的类型
举例
1 127.0.0.1:6379> set name zhangsan
2 OK
3 127.0.0.1:6379> get name
4 "zhangsan"
5 127.0.0.1:6379> set id 123
6 OK
7 127.0.0.1:6379> get id
8 "123"
5.5.2、Hash(哈希字典),适合存储对象
举例
1 127.0.0.1:6379> hmset stu name lisi age 24 sex 男
2 OK
3 127.0.0.1:6379> hget stu name
4 "lisi"
5 127.0.0.1:6379> hget stu age
6 "24"
7 127.0.0.1:6379> hget stu sex
8 "\xe7\x94\xb7"
9 ###--raw 解决中文乱码问题
10 [root@server1 src]# redis-cli -h 127.0.0.1 -p 6379 --raw
11 127.0.0.1:6379> hget stu sex
12 男
5.5.3、List(列表)
举例
1 127.0.0.1:6379> lpush hobby play
2 1
3 127.0.0.1:6379> lpush hobby read
4 2
5 127.0.0.1:6379> lpush hobby sport
6 3
7 127.0.0.1:6379> lrange hobby 0 5
8 sport
9 read
10 play
11 127.0.0.1:6379> lrange hobby 0 0
12 sport
13 127.0.0.1:6379> lrange hobby 1 1
14 read
15 127.0.0.1:6379> lrange hobby 2 2
16 play
17
18 ###最先放入的数据拍照最后,就相当于在瓶子里放东西,最后被放进去的,取出来时是第一个被取出来的
5.5.4、Set(集合)是string类型的无序的集合
集合是通过哈希表实现的,所有添加,删除,查找的复杂度都是0(1)
作用场景:
①共同好友
②利用唯一性,统计访问网站的所有独立ip
③好友推荐时,根据tag求交集,大于某个阈值就可以推荐
举例
1 127.0.0.1:6379> sadd color red green yellow orange
2 4
3 127.0.0.1:6379> smembers color
4 green
5 red
6 orange
7 yellow
8 127.0.0.1:6379> sadd color orange
9 0
10 ##去重
5.5.5、zset(有序集合)
举例
1 127.0.0.1:6379> zadd color1 0 red
2 1
3 127.0.0.1:6379> zadd color1 0 blue
4 1
5 127.0.0.1:6379> zadd color1 1 green
6 1
7 127.0.0.1:6379> zadd color1 1 yellow
8 1
9 127.0.0.1:6379> zrangebyscore color1 0 10
10 blue
11 red
12 green
13 yellow
14 127.0.0.1:6379> zadd color1 0.5 orange
15 1
16 127.0.0.1:6379> zrangebyscore color1 0 10
17 blue
18 red
19 orange
20 green
21 yellow
22
23 ##插入的0.5在0和1之间
六、Redis持久化
6.1、持久化概述
6.1.1、Redis是运行在内存中,内存中的数据断电丢失
6.1.2、为了能够重用Redis数据,或者防止系统故障,需要将Redis中的数据写入到磁盘空间中,即持久化
6.2、持久化分类
6.2.1、RDB方式:创建快照的方式获取某一时刻Redis中所有数据的副本
6.2.2、AOF方式:将执行的写命令写到文件的末尾,以日志的方式来记录数据的变化
6.3、RDB持久化
6.3.1、Redis的默认持久化方式
6.3.2、默认文件名dump.rdb
6.3.3、触发条件
①在指定的时间间隔内,执行指定次数的写操作(配置文件控制)
②执行save或者是bgsave(异步)命令
③执行flushall命令,清空数据库所有数据
④执行shutdown命令,保证服务器正常关闭且不丢失任何数据
6.3.4、优缺点
①适合大规模的数据恢复
②如果业务对数据完整性和一致性要求不高,RDB是很好的选择
③数据的完整性和一致性不高
④备份时占用内存
6.3.5、通过RDB文件恢复数据
将dump.rdb文件拷贝到redis的安装目录的bin目录下,重启redis服务即可
6.3.6、配置文件选项
1 [root@server1 src]# vim /etc/redis/6379.conf
2 save 900 1 #900秒之内至少一次写操作
3 save 300 10 #300秒之内至少发生10次写操作
4 save 60 10000 #60秒之内发生至少10000次写操作,只要满足其一都会触发快照操作,注释所有的save项表示关闭RDB
5 dbfilename dump.rdb #RDB文件名称
6 dir /var/lib/redis/6379 #RDB文件路径
7 rdbcompression yes #是否进行压缩
6.4、AOF持久化
6.4.1、Redis默认不开启
6.4.2、弥补RDB的不足(数据的不一致性)
6.4.3、采用日志的形式来记录每个写操作,并追加到文件中
6.4.4、Redis重启会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作
6.4.5、根据AOF文件恢复数据
将appendonly.aof文件拷贝到Redis的安装目录的bin目录下,重启Redis服务即可
6.4.6、配置文件选项
1 [root@server1 src]# vim /etc/redis/6379.conf
2 appendonly yes #开启AOF持久化
3 appendfilename "appendonly.aof" #AOF文件名称
4 # appendfsync always
5 appendfsync everysec #always:同步持久化,每次发生数据变化会立刻写入磁盘;everysec:默认推荐,每秒异步记录一次(默认值);no:不同步,交给操作系统决定如何同步
6 # appendfsync no
7 aof-load-truncated yes #忽略最后一条可能存在问题的指令
1 [root@server1]# cd /var/lib/redis/6379/
2 [root@server1 6379]# ll
3 总用量 8
4 -rw-r--r--. 1 root root 0 11月 10 12:06 appendonly.aof
5 -rw-r--r--. 1 root root 175 11月 10 12:26 dump.rdb
6 -rw-r--r--. 1 root root 781 11月 10 12:26 nodes-6379.conf
七、测试
7.1、为6379的Redis服务器发生100并发连接数10000个请求数
1 [root@server1 src]# redis-benchmark -h 20.0.0.10 -p 6379 -c 100 -n 10000
2 ====== PING_INLINE ======
3 10000 requests completed in 0.05 seconds
4 100 parallel clients
5 3 bytes payload
6 keep alive: 1
7
8 99.05% <= 1 milliseconds
9 99.58% <= 2 milliseconds
10 100.00% <= 2 milliseconds
11 200000.00 requests per second
12 ###省略部分内容###
13 ====== MSET (10 keys) ======
14 10000 requests completed in 0.05 seconds
15 100 parallel clients
16 3 bytes payload
17 keep alive: 1
18
19 100.00% <= 0 milliseconds
20 217391.30 requests per second
7.2、存取大小为100字节的数据包的性能
1 [root@master1 src]# redis-benchmark -h 20.0.0.10 -p 6379 -q -d 100
2 PING_INLINE: 221238.94 requests per second
3 PING_BULK: 216450.20 requests per second
4 SET: 229357.80 requests per second
5 GET: 226757.36 requests per second
6 INCR: 224215.23 requests per second
7 LPUSH: 175746.92 requests per second
8 RPUSH: 168067.22 requests per second
9 LPOP: 203665.98 requests per second
10 RPOP: 219298.25 requests per second
11 SADD: 222717.16 requests per second
12 HSET: 227790.42 requests per second
13 SPOP: 224719.11 requests per second
14 LPUSH (needed to benchmark LRANGE): 172413.80 requests per second
15 LRANGE_100 (first 100 elements): 84745.77 requests per second
16 LRANGE_300 (first 300 elements): 33233.63 requests per second
17 LRANGE_500 (first 450 elements): 22794.62 requests per second
18 LRANGE_600 (first 600 elements): 16926.20 requests per second
19 MSET (10 keys): 185873.61 requests per second
7.3、测试本机上Redis服务在进行set与lpush操作时的性能
1 [root@master1 src]# redis-benchmark -h 20.0.0.10 -p 6379 -t set,lpush -n 100000 -q
2 SET: 233644.86 requests per second
3 LPUSH: 204081.62 requests per second
八、Redis性能管理
8.1、内存碎片率
8.1.1、操作系统分配的内存值used_memory_rss除以Redis使用的内存值used_memory计算得出
8.1.2、内存碎片是由操作系统低效的分配/回收物理内存导致的
不连续的物理内存分配
8.1.3、跟踪内存碎片率对理解Redis实例的资源性能是非常重要的
①内存碎片率稍大于1是合理的,这个值表示内存碎片率比较低
②内存碎片率超过1.5,说明Redis消耗了实际需要物理内存的150%,其中50%是内存碎片率
③内存碎片率低于1的,说明Redis内存分配超出了物理内存,操作系统正在进行内存交换
8.2、内存使用率
8.2.1、redis实例的内存使用率超过可用最大内存,操作系统将开始进行内存与swap空间交换
8.2.2、避免内存交换
①针对缓存数据大小选择
②尽可能的使用Hash数据结构
③设置key的过期时间
8.3、回收key
8.3.1、保证合理分配redis有限的内存资源
8.3.2、当达到设置的最大阀值时,需选择一种key的回收策略
①默认情况下回收策略是禁止删除
②redis.conf配置文件中修改maxmemory-policy属性值
1)volatile-lru:使用LRU算法从已设置过期时间的数据集合中淘汰数据
2)volatile-ttl:从已设置过期时间的数据集合中挑选即将过期的数据淘汰
3)volatile-random:从已设置过期时间的数据集合中随机挑选数据淘汰
4)allkeys-lru:使用LRU算法从所有数据集合中淘汰数据
5)allkeys-random:从数据集合中任意选择数据淘汰
6)no-enviction:禁止淘汰数据