1. Redis简介
Redis是非关系型数据库(nosql),数据保存在内存中,安全性低,但读取速度快。
Redis主要存储变化较快且数据不是特别重要的数据。
Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)和zset(有序集合)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类keyvalue存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Python,Ruby,Erlang,PHP客户端,使用很方便。
简而言之redis是属于非关系型数据库,存储结构是:key-value,内存-磁盘的存储方式。
2. Redis应用场景
1> 登录会话存储:存储在redis中,与memcached相比,数据不会丢失。
2> 排行版/计数器:比如一些秀场类的项目,经常会有一些前多少名的主播排名。还有一些文章阅读量的技术,或者新浪微博的点赞数等。
3>作为消息队列:比如celery就是使用redis作为中间人。
4> 当前在线人数:还是之前的秀场例子,会显示当前系统有多少在线人数。
5> 一些常用的数据缓存:比如我们的BBS论坛,板块不会经常变化的,但是每次访问首页都要从mysql中获取,可以在redis中缓存起来,不用每次请求数据库。
6> 把前200篇文章缓存或者评论缓存:一般用户浏览网站,只会浏览前面一部分文章或者评论,那么可以把前面200篇文章和对应的评论缓存起来。用户访问超过的,就访问数据库,并且以后文章超过200篇,则把之前的文章删除。
7> 好友关系:微博的好友关系使用redis实现。
8> 发布和订阅功能:可以用来做聊天软件。
简而言之,Redis可以把内存数据同步到磁盘,即可以将数据持久化。
3. Redis的持久化(数据库备份)
redis持久化会在磁盘上依赖两个文件
数据文件:rdb
日志文件:aof
redis实现持久化两种机制
RDB:周期的将内存中的数据备份到磁盘
AOF:借助于一个日志文件,这个文件会记录每次操作
4. Redis中的数据类型
字符类型
列表类型
有序集合类型
无序集合类型
哈希表类型
5. Redis和memcached的比较
memcached |
redis |
|
类型 |
纯内存数据库 |
内存磁盘同步数据库 |
数据类型 |
在定义value时就要固定数据类型 |
不需要 |
虚拟内存 |
不支持 |
支持 |
过期策略 |
支持 |
支持 |
存储数据安全 |
不支持 |
可以将数据同步到dump.rdb中 |
灾难恢复 |
不支持 |
可以将磁盘中的数据恢复到内存中 |
分布式 |
支持 |
主从同步 |
订阅与发布 |
不支持 |
支持 |
6.Redis的使用
6.1 下载安装
直接使用yum安装的Redis版本是3.2的,最新版的安装可以从官网下载安装包进行解压编译安装。
1> 下载安装包,解压
[root@localhost ~]# wget http://download.redis.io/releases/redis-5.0.0.tar.gz [root@localhost ~]# tar -xf redis-5.0.0.tar.gz [root@localhost ~]# ls redis-5.0.0.tar.gz redis-5.0.0
2> 下载编译环境
[root@localhost ~]# yum install gcc gcc-c++ -y
3> 编译安装
[root@localhost ~]# cd redis-5.0.0 [root@localhost redis-5.0.0]# make …….. make[1]: Leaving directory `/root/redis-5.0.0/src'
4> 将启动文件拷贝到环境变量
[root@localhost redis-5.0.0]# ls 00-RELEASENOTES COPYING Makefile redis.conf runtest-sentinel tests BUGS deps MANIFESTO runtest sentinel.conf utils CONTRIBUTING INSTALL README.md runtest-cluster src [root@localhost ~]# mv redis-5.0.0 /usr/local/redis #移动安装文件 [root@localhost ~]# cd /usr/local/reids/ [root@localhost reids]# cp src/redis-server /usr/bin/ [root@localhost reids]# cp src/redis-cli /usr/bin/
5> 启动Redis数据库服务
yum安装的直接用命令systemctl restart redis,编译安装的使用配置文件启动,一个主机上可以运行多个Redis实例。
一般来说,第三方软件安装在/usr/local或者/opt下。
Redis依赖配置文件redis.conf启动。
[root@localhost reids]# redis-server redis.conf #一大堆文件# [root@localhost reids]# ss -tnl LISTEN 0 128 192.168.16.4:6379 *:*
6.2 Redis的配置文件
[root@localhost redis-5.0.0]# vim redis.conf ……. # dbid is a number between 0 and 'databases'-1 databases 16 #在Redis数据库当中数据库以数字形式管理,默认最多有16个数据库,此处上限可以更改 ……. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bind 192.168.16.4 #bind后面的地址应该改为主机地址而不是默认的回环地址,在客户端基于该ip进行登录。 ….. # If port 0 is specified Redis will not listen on a TCP socket. port 6379 #默认端口号6379 …… # Note that Redis will write a pid file in /var/run/redis.pid when daemonized. daemonize yes #守护进程,默认是no,改为yes可避免启动时出现的大堆文件
6.3连接数据库
[root@localhost reids]# redis-cli -p 6379 -h 192.168.16.4 192.168.16.4:6379>
6.4 切换数据库
Redis数据库以数字形式管理,默认为0,默认数据库范围0-15,与mariadb的use切换数据库不同,Redis直接用select+数字进行数据库切换。同时Redis数据库在输入命令后会进行人性化的命令提示。
192.168.16.4:6379> select 9 OK 192.168.16.4:6379[9]> select 0 OK 192.168.16.4:6379>
6.5 添加
格式: set key value (关键字 值)
将字符串的value关联到key,如果可以已经持有其他值没set命令就覆写旧值,无视其类型。并且默认的过期时间是永久,即永远不会过期。
#添加用户 192.168.16.4:6379> set username zxj OK #查看添加的内容 192.168.16.4:6379> get username "zxj" #查看所有的key值 192.168.16.4:6379> set username2 wrl OK 192.168.16.4:6379> keys * 1) "username" 2) "username"
6.6 删除
格式:del key
192.168.16.4:6379> del username (integer) 1 192.168.16.4:6379> keys * 1) "username2"
6.7 设置过期时间
格式:set key value EX timeout
192.168.16.4:6379> set username zxj ex 30 #设置过期时间为30秒,30秒后到期过期,ex:expiration EX seconds|PX milliseconds ok 192.168.16.4:6379> keys * 1) "username2" 2) "username" 192.168.16.4:6379> keys * 1) "username2"
6.8 查看过期时间
格式: TTL key
192.168.16.4:6379> set username3 zxcv ex 60 OK 192.168.16.4:6379> ttl username3 (integer) 51 192.168.16.4:6379> ttl username3 (integer) 21
6.9 列表操作(list)
在列表左边添加元素(类似于弹匣装弹)。
格式:lpush key value
192.168.16.4:6379> lpush language python c++ java #value值可以为多个 (integer) 3
查看列表中的元素
格式:lrange key start stop,左边第一位为0, 右边第一位为-1;
192.168.16.4:6379> lrange language 0 -1 #查看列表中的所有元素 1) "java" 2) "c++" 3) "python" 192.168.16.4:6379> lrange language 0 1 1) "java" 2) "c++" 192.168.16.4:6379> lrange language -2 -1 1) "c++" 2) "python"
在列表右边添加元素(正常添加)
格式:rpush key value
192.168.16.4:6379> lrange language 0 -1 1) "java" 2) "c++" 3) "python" 4) "jinjia2"
移除列表中的元素
移除并返回列表key的头元素
格式:lpop key
192.168.16.4:6379> lpop language "java"
移除并返回列表的尾元素
格式:rpop key
192.168.16.4:6379> rpop language "jinjia2"
#pop操作后表中元素 192.168.16.4:6379> lrange language 0 -1 1) "c++" 2) "python"
指定返回第几个元素
格式:lindex key index
192.168.16.4:6379> lrange language 0 -1 1) "jingjia2" 2) "c++" 3) "c" 4) "java" 5) "paython" 6) "golang" 7) "c++" 8) "python" 192.168.16.4:6379> lindex language 1 "c++" 192.168.16.4:6379> lindex language 2 "c" 192.168.16.4:6379> lindex language 4 "paython" 192.168.16.4:6379> lindex language 0 "jingjia2"
获取列表中的元素个数(查看长度)
格式:llen key
192.168.16.4:6379> llen language (integer) 8
删除指定的元素
格式:lrem key count value (删除count个value)
根据参数 count 的值,移除列表中与参数 value 相等的元素。count的值可以是以下几种:
count > 0:从表头开始向表尾搜索,移除与value相等的元素,数量为count。
count < 0:从表尾开始向表头搜索,移除与 value相等的元素,数量为count的绝对值。
count = 0:移除表中所有与value 相等的值。
192.168.16.4:6379> rpush language python python python python (integer) 12 192.168.16.4:6379> lrange language 0 -1 1) "jingjia2" 2) "c++" 3) "c" 4) "java" 5) "paython" 6) "golang" 7) "c++" 8) "python" 9) "python" 10) "python" 11) "python" 12) "python 192.168.16.4:6379> lrem language 3 python #删除三个Python (integer) 3 192.168.16.4:6379> lrange language 0 -1 1) "jingjia2" 2) "c++" 3) "c" 4) "java" 5) "paython" 6) "golang" 7) "c++" 8) "python" 9) "python"
6.10 set集合的操作
集合中的元素不可重复,自动去重
添加元素
格式:sadd see value1 ….
192.168.16.4:6379> sadd lan python java c c++ python python java (integer) 4 #自动去重
查看集元素
格式:smembers set
192.168.16.4:6379> SMEMBERS lan 1) "c" 2) "java" 3) "python" 4) "c++"
删除集合元素
格式:srem set member
192.168.16.4:6379> SREM lan java (integer) 1 192.168.16.4:6379> SMEMBERS lan 1) "python" 2) "c++" 3) "c"
查看集合中的元素个数
格式:scard set
192.168.16.4:6379> SCARD lan (integer) 3
获取多个集合的交集
格式:sinter set1 set2
192.168.16.4:6379> SMEMBERS lan 1) "python" 2) "c++" 3) "c" 4) "xiaowu" 5) "java" 192.168.16.4:6379> SMEMBERS lan1 1) "dupu" 2) "liwang" 3) "nihao" 4) "java" 5) "xiaowu" 192.168.16.4:6379> SINTER lan1 lan 1) "java" 2) "xiaowu" 192.168.16.4:6379> SINTER lan lan1 1) "xiaowu" 2) "java"
获取多个集合的并集
格式:sunion set1 set2
192.168.16.4:6379> SUNION lan lan1 1) "c++" 2) "c" 3) "dupu" 4) "liwang" 5) "nihao" 6) "xiaowu" 7) "java" 8) "python"
6.11 hash,哈希操作
哈希可以理解为表的嵌套,表中含有表。
添加新值
格式:hset key filed value
192.168.16.4:6379> HSET zxj age 23 (integer) 1 192.168.16.4:6379> HSET zxj high 150 (integer) 1 192.168.16.4:6379> HSET zxj gender women (integer) 1
取出哈希表中filed对应的值
格式:hget key filed
192.168.16.4:6379> HGET zxj gender "women"
删除哈希表中filed对应的值
格式:hdel key filed
192.168.16.4:6379> HDEL zxj gender (integer) 1 192.168.16.4:6379> hget zxj gender (nil)
获取哈希表中所有的filed和value
格式:hgetall key
192.168.16.4:6379> hgetall zxj 1) "age" 2) "23" 3) "high" 4) "150"
获取哈希表中所有的filed
格式:hkeys key
192.168.16.4:6379> hkeys zxj 1) "age" 2) "high"
获取哈希表中所有的value
格式:hvals key
192.168.16.4:6379> hvals zxj 1) "23" 2) "150"
判断哈希表中是否存在某个filed
格式:hexists key filed
192.168.16.4:6379> hexists zxj gender (integer) 0 192.168.16.4:6379> hexists zxj age (integer) 1
获取哈希表中总的键值对
格式:hlen key
192.168.16.4:6379> hlen zxj (integer) 2
6.12 对事务的操作
Redis事务可以一次执行多个命令,事务具有以下特征:
隔离操作:事务中的所有命令都会序列化、按顺序地执行,不会被其他命令打扰。
原子操作:事务中的命令要么全部被执行,要么全部都不执行。
开启事务:multi
提交:exec
取消事务:discard
#在一个窗口开启事务 192.168.16.4:6379> MULTI OK #创建两条数据 192.168.16.4:6379> set friendone zxj QUEUED 192.168.16.4:6379> set friendtwo wrl QUEUED #此时尚未提交,在打开一个窗口进行查看,由于隔离性,并没有添加两条数据 [root@localhost ~]# redis-cli -p 6379 -h 192.168.16.4 192.168.16.4:6379> keys * (empty list or set) #返回窗口提交 192.168.16.4:6379> exec 1) OK 2) OK #再去另外一个窗口查看 192.168.16.4:6379> keys * 1) "friendone" 2) "friendtwo"
6.13 订阅与发布
订阅某个频道的消息
格式:subscribe channel
#在窗口以订阅频道88.7(频道值随便设置) 192.168.16.4:6379> SUBSCRIBE 88.7 Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "88.7" 3) (integer) 1 #光标一直悬浮停留准备接收信息
给某个频道发布消息
格式:publish channel message 从某个频道发布信息
#在窗口2 发布信息 192.168.16.4:6379> PUBLISH 88.7 westlife (integer) 1 192.168.16.4:6379> PUBLISH 88.7 "westlife's songs are very populary between 90s" (integer) 1 #在窗口1查看订阅的频道 1) "message" 2) "88.7" 3) "westlife" 1) "message" 2) "88.7" 3) "westlife's songs are very populary between 90s"
Redis的订阅与分布是一种异步操作