Redis简介:

Redis 是完全开源免费的,遵守 BSD(开源许可协议) 协议,是一个高性能的 key - value 数据库

Redis 与 其他 key - value 缓存产品有以下三个特点:

Redis 支持数据持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。 Redis 不仅仅支持简单的 key -
value 类型的数据,同时还提供 list,set,zset,hash 等数据结构的存储 Redis 支持数据的备份,即 master -slave 模式的数据备份

Redis的优势。

性能极高 – Redis 读的速度是 110000 次 /s, 写的速度是 81000 次 /s 。
丰富的数据类型 - Redis 支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
原子性 - Redis 的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过 MULTI 和 EXEC 指令包起来。
其他特性 - Redis 还支持 publish/subscribe 通知,key 过期等特性。

redis安装:

[root@Centos6 ~]# yum info redis
Loaded plugins: fastestmirror, refresh-packagekit, security
Loading mirror speeds from cached hostfile
 * base: mirrors.ustc.edu.cn
 * extras: mirrors.163.com
 * updates: mirrors.163.com
file:///mnt/repodata/repomd.xml: [Errno 14] Could not open/read file:///mnt/repodata/repomd.xml
Trying other mirror.
base                                                                                                                      | 3.7 kB     00:00     
epel                                                                                                                      | 4.7 kB     00:00     
extras                                                                                                                    | 3.4 kB     00:00     
updates                                                                                                                   | 3.4 kB     00:00     
Installed Packages
Name        : redis
Arch        : x86_64
Version     : 3.2.12
Release     : 2.el6
Size        : 1.3 M
Repo        : installed
From repo   : epel
Summary     : A persistent key-value database
URL         : http://redis.io
License     : BSD
Description : Redis is an advanced key-value store. It is often referred to as a data
            : structure server since keys can contain strings, hashes, lists, sets and
            : sorted sets.
            : 
            : You can run atomic operations on these types, like appending to a string;
            : incrementing the value in a hash; pushing to a list; computing set
            : intersection, union and difference; or getting the member with highest
            : ranking in a sorted set.
            : 
            : In order to achieve its outstanding performance, Redis works with an
            : in-memory dataset. Depending on your use case, you can persist it either
            : by dumping the dataset to disk every once in a while, or by appending
            : each command to a log.
            : 
            : Redis also supports trivial-to-setup master-slave replication, with very
            : fast non-blocking first synchronization, auto-reconnection on net split
            : and so forth.
            : 
            : Other features include Transactions, Pub/Sub, Lua scripting, Keys with a
            : limited time-to-live, and configuration settings to make Redis behave like
            : a cache.
            : 
            : You can use Redis from most programming languages also.
[root@Centos6 ~]# yum install redis -y
[root@Centos6 ~]# rpm -ql redis
/etc/logrotate.d/redis
/etc/rc.d/init.d/redis
/etc/rc.d/init.d/redis-sentinel
/etc/redis-sentinel.conf
/etc/redis.conf              配置文件
/etc/security/limits.d/95-redis.conf
/usr/bin/redis-benchmark
/usr/bin/redis-check-aof
/usr/bin/redis-check-rdb
/usr/bin/redis-cli            客户端连接服务端
/usr/bin/redis-sentinel
/usr/bin/redis-server         启动服务端
/usr/libexec/redis-shutdown
/usr/share/doc/redis-3.2.12
/usr/share/doc/redis-3.2.12/00-RELEASENOTES
/usr/share/doc/redis-3.2.12/BUGS
/usr/share/doc/redis-3.2.12/CONTRIBUTING
/usr/share/doc/redis-3.2.12/COPYING
/usr/share/doc/redis-3.2.12/MANIFESTO
/usr/share/doc/redis-3.2.12/README.md
/usr/share/man/man1/redis-benchmark.1.gz
/usr/share/man/man1/redis-check-aof.1.gz
/usr/share/man/man1/redis-check-rdb.1.gz
/usr/share/man/man1/redis-cli.1.gz
/usr/share/man/man1/redis-sentinel.1.gz
/usr/share/man/man1/redis-server.1.gz
/usr/share/man/man5/redis-sentinel.conf.5.gz
/usr/share/man/man5/redis.conf.5.gz
/var/lib/redis       redis的数据目录。
/var/log/redis
/var/run/redis

Redis支持的数据类型

redis支持5种数据类型:string(字符串),hash(哈希),list(列表),set(集合),zset(sorted set:有序集合)

string(字符串)

string 是 redis 最基本的数据类型。一个 key 对应一个 value。

string 是二进制安全的。也就是说 redis 的 string 可以包含任何数据。比如 jpg 图片或者序列化的对象。

string 类型是 redis 最基本的数据类型,string 类型的值最大能存储 512 MB

127.0.0.1:6379> set name yan    定义一个字符串,赋予值。
OK
127.0.0.1:6379> get name        查看字符串的值
"yan"
127.0.0.1:6379> set ip 0.0.0.0
OK
127.0.0.1:6379> get ip
"0.0.0.0"
127.0.0.1:6379> set name 123
OK
127.0.0.1:6379> get name
"123"

hash数据类型。

Redis hash 是一个键值对(key - value)集合。Redis hash 是一个 string 类型的 key 和 value 的映射表,hash 特别适合用于存储对象。
理解:可以将 hash 看成一个 key - value 的集合。也可以将其想成一个 hash 对应着多个 string。
与 string 区别:string 是 一个 key - value 键值对,而 hash 是多个 key - value 键值对。

127.0.0.1:6379> help @hash   通过这个查看hash相关命令操作。
例如:
127.0.0.1:6379> hset h1 a mon         定义一个hash数据类型h1 ,a字符串值为mon
(integer) 0 
127.0.0.1:6379> hget h1 a
"mon"
127.0.0.1:6379> hset h1 b tue         定义一个hash数据类型h1 ,b字符串值为tue 这是一个字符串集合。
(integer) 0
127.0.0.1:6379> hget h1 b             查看hash h1 b的值
"tue"
127.0.0.1:6379> hkeys h1              查看hash  h1中的键
1) "a"
2) "b"
127.0.0.1:6379> hvals h1             查看hash  h1中键的值
1) "mon" 
2) "tue"
127.0.0.1:6379> hlen h1              查看h1中的元素个数。
(integer) 2
127.0.0.1:6379> hgetall h1
1) "a"
2) "mon"
3) "b"
4) "tue"

list数据类型。

redis 列表是简单的字符串列表,按照插入顺序排序。我们可以网列表的左边或者右边添加元素  注意:list 内的元素是可重复的。

127.0.0.1:6379> help @list
127.0.0.1:6379> lpush l1 mon    定义一个列表l1 插入一个值为mon
(integer) 1
127.0.0.1:6379> lindex l1 0     查看列表l1中的0号索引的值
"mon"  
127.0.0.1:6379> lpush l1 sun    往l1列表中插入一个值在mon的左边
(integer) 2 
127.0.0.1:6379> lindex l1 1     查看列表l1中的1号索引的值
"mon"
127.0.0.1:6379> rpush l1 true    往l1列表中插入一个值在mon的右边
(integer) 3
127.0.0.1:6379> lindex l1 2      查看列表l1中的2号索引的值
"true"
127.0.0.1:6379> lset l1 1 fri    将l1列表的1号索引值改为fri
OK 
127.0.0.1:6379> lindex l1 1
"fri"
127.0.0.1:6379> rpop l1         这表示将列表l1依次删除,数据删除从右往左删除。
"true"
127.0.0.1:6379>

set数据类型。

redis 的 set 是字符串类型的无序集合。集合是通过哈希表实现的,因此添加、删除、查找的复杂度都是 O(1)
注意:redis 的 list 不同的是 set 中的字符串集合元素不能重复,但是 list 可以。

127.0.0.1:6379> sadd w1 mon tue wed thu fre sat sun  添加一个set数据类型集合,w1
(integer) 2
127.0.0.1:6379> sadd w2 tue thu day            添加一个set数据类型集合 w2
(integer) 0
127.0.0.1:6379> sinter w1 w2               查看w1和w2集合的并集
1) "thu"
2) "tue"
127.0.0.1:6379> sunion w1 w2           查看w1和w2的交际
1) "mon"
2) "wed"
3) "thu"
4) "tue"
5) "sat"
6) "fre"
7) "sun"
8) "day"
127.0.0.1:6379> spop w1            表示随便弹出一个w1集合中的数据
"sun"
127.0.0.1:6379> sismember w1 fri   判断w1集合中是否又fri这个字符串  1表示有,0表示没有
(integer) 0
127.0.0.1:6379>

zset数据类型

redis zset 和 set 一样都是 字符串类型元素的集合,并且集合内的元素不能重复。

不同的是,zset 每个元素都会关联一个 double 类型的分数。redis 通过分数来为集合中的成员进行从小到大的排序。

zset 的元素是唯一的,但是分数(score)却可以重复。

127.0.0.1:6379> zadd weekday1 1 mon 2 tue 3 wed   定义一个zset 1为mon ,2,tue
(integer) 0 
127.0.0.1:6379> zcard weekday1           查看weekday1中的元素。    
(integer) 3
127.0.0.1:6379> zscore weekday1 tue      查看分数大小
"2"
127.0.0.1:6379> zscore weekday1 mon      
"1"
127.0.0.1:6379> zrank weekday1 mon      查看内置索引大小
(integer) 0
127.0.0.1:6379> zrange weekday1 0 2     查看索引0-2范围的值
1) "mon"
2) "tue"
3) "wed"

加粗样式redis的发布订阅:
简介:Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。Redis 客户端可以订阅任意数量的频道。

例如:
127.0.0.1:6379> SUBSCRIBE yan           定义一个消息队列频道,名称为yan
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "yan"
3) (integer) 1
1) "message"
2) "yan"
3) "hello"

127.0.0.1:6379> publish yan hello      向频道中发生消息。
(integer) 1
127.0.0.1:6379> 

127.0.0.1:6379> UNSUBSCRIBE yan    这代表取消订阅的频道。
1) "unsubscribe"
2) "yan"
3) (integer) 0


第二种:定义频道时还支持模式订阅,支持正则表达式。
127.0.0.1:6379> PSUBSCRIBE "i.[to]"   设定模式订阅多个频道。
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "i.[to]"
3) (integer) 1
1) "pmessage"
2) "i.[to]"
3) "i.o"
4) "hello"

127.0.0.1:6379> PUBLISH i.o hello
(integer) 1
127.0.0.1:6379>

redis事务:

(1)redis 事务一次可以执行多条命令,服务器在执行命令期间,不会去执行其他客户端的命令请求。

(2)事务中的多条命令被一次性发送给服务器,而不是一条一条地发送,这种方式被称为流水线,它可以减少客户端与服务器之间的网络通信次数从而提升性能。
Redis 最简单的事务实现方式是使用 MULTI 和 EXEC 命令将事务操作包围起来。
批量操作在发送 EXEC 命令前被放入队列缓存。
收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余命令依然被执行。也就是说 Redis 事务不保证原子性。
在事务执行过程中,其他客户端提交的命令请求不会插入到事务执行命令序列中。

(3)一个事务从开始到执行会经历以下三个阶段:
开始事务。
命令入队。
执行事务。

redis事务的相关命令:
1. DISCARD 取消事务,放弃执行事务块内的所有命令。

2. EXEC 执行所有事务块内的命令。

3. MULTI 标记一个事务块的开始。

4. UNWATCH 取消 WATCH 命令对所有 key 的监视。

5. WATCH key [key …]监视一个 (或多个) key ,如果在事务执行之前这个 (或这些) key 被其他命令所改动,那么事务将被打断。

例如:实现简单事务的列子:
127.0.0.1:6379> multi     表示开启一个事务。
OK
127.0.0.1:6379> set date "2020-6-23"
QUEUED
127.0.0.1:6379> get date
QUEUED
127.0.0.1:6379> set ip 123
QUEUED
127.0.0.1:6379> get ip
QUEUED
127.0.0.1:6379> exec     当我们发起exec之前的一些操作都是放在缓存队列中,一执行exec,服务端不在接收客户端请求,而去处理事务相关指令。
1) OK
2) "2020-6-23"
3) OK
4) "123"
127.0.0.1:6379> 

注意:当我们在执行事务命令过程中,命令书写错误,那么在执行exec时,事务不予执行。
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set a aaa
QUEUED
127.0.0.1:6379> set b ccc
QUEUED
127.0.0.1:6379> set c bbb
QUEUED
127.0.0.1:6379> sett a ip
(error) ERR unknown command 'sett'
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> 

watch命令的使用:
127.0.0.1:6379> watch ip     我先watch监控一个键为ip
OK
127.0.0.1:6379> MULTI        开启事务
OK
127.0.0.1:6379> set ip 124   定义键ip的值
QUEUED
127.0.0.1:6379> get ip
QUEUED

另起终端,连接redis
127.0.0.1:6379> set ip 345    修改一下ip的键的值
OK
127.0.0.1:6379> exec   在执行事务,表示为空。表示被打断的。
(nil)

redis持久化,分为两种,RDB持久化,AOF持久化

Redis 是内存型数据库,为了保证数据在断电后不会丢失,需要将内存中的数据持久化到硬盘上。

RDB持久化:周期性保存

(1)将某个时间点的所有数据都存放到硬盘上。

(2)可以将快照复制到其他服务器从而创建具有相同数据的服务器副本。

(3)如果系统发生故障,将会丢失最后一次创建快照之后的数据。

(4)如果数据量大,保存快照的时间会很长。
(5)RDB(默认启用的):snapshot:二进制格式数据文件,快照式存储。按照事先定制的策略,周期性的将数据保存至磁盘;数据文件默认为dump.rdb
(6)客户端也可以显示使用SAVE或BGSAVE命令启动快照保存机制;

RDB的两种方式:

save:同步,指定rdb的周期性,在主线程中保存快照;此时会阻塞所有客户端请求;客户端也可以使用save命令保存。 
BGSAVE:异步,一但启动,生成一个子进程,我们主进程处理用户请求,而子进程负责将内存中的数据快照到磁盘中去。

RDB的相关配置:
stop-write-on-bgsave-error  yes   表示在进行快照备份时,在发生错误时是否停止写操作。
rdbcompression  yes  这里表示数据要不要压缩。
rdbchecksum  yes    是否开启校验码。
dbfilename  dump.rdb
dir  /var/lib/redis

AOF持久化:

(1)将写命令添加到 AOF 文件(append only file)末尾。是通过记录每一次写操作至指定的文件尾部实现持久化;当redis重启时,可通过重新执行文件中的命令在内存重建数据库。

(2)使用 AOF 持久化需要设置同步选项,从而确保写命令同步到磁盘文件上的时机。

(3)这是因为对文件进行写入并不会马上将内容同步到磁盘上,而是先存储到缓冲区,然后由操作系统决定什么时候同步到磁盘。

AOF的重写过程:
(1)redis主进程通过fork创建子进程

(2)子进程根据内存中的数据创建数据库重建命令序列于临时文件中;

(3)父进程继承client的请求,并会把这些请求中的写的操作继续追加至原来的AOF文件。额外的,这些新的写请求还会被放置于一个缓冲队列中‘

(4)子进程重写完成中,会通知父进程,父进程把缓冲中的命令写到临时文件中。

(5)父进程用临时文件替换老的aof文件。

随着服务器写请求的增多,AOF 文件会越来越大。Redis 提供了一种将 AOF 重写的特性,能够去除 AOF 文件中的冗余写命令。
bgrewriteaof命令:AOF文件重写;不会读取正在使用的AOF文件,而通过将内存中的数据以命令的方式保存到临时文件中,完成之后替换
原来的AOF文件

如何打开AOF?
相关参数:
appendonly  no    表示不打开AOF功能。
appendfilename  "appendonly.aof"   文件位置
appendfsync {always|everysec|no}    always(表示一旦发生写操作,就立即同步到磁盘中)everysec(表示通知内核每秒钟写一次) no(表示不通知内核随意时间写)
no-appendfsync-on-rewrite  no   表示对新写的操作不同步到磁盘中,
auto-aof-rewrite-percentage  100  当前的AOF的文件
auto-aof-rewrite-min-size 64mb  指明文件大小达到64m,才进行重写功能。

注意:持久本身不能取代备份,还应该制定备份策略,对redis数据库定期进行备份。

RDB与AOF同时启用:

(1)BGSAVE和BGREWRITEAOF不会同时执行;
(2)在redis服务器启用用于恢复数据库时,会先使用AOF