Redis简介
1.NoSQL(non-relational,Not Only SQL)
NoSQL泛指非关系型的数据库,区别于关系型数据库,它们不保证关系数据的ACID特性。
NoSQL是不同于传统的关系型数据库的数据库管理系统的统称。NoSQL与关系型数据库的区别在于NoSQL不使用SQL作为查询语言。NoSQL数据存储可以不需要固定的表格模式,NoSQL是基于键值对的,可以想象成表中的主键和值的对应关系。
2.Redis是什么?Redis使用场景?
Redis定义:Redis是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。它支持多种类型的数据结构,如字符串(strings)、散列(hashes)、列表(list)、集合(sets)、有序集合(sorted sets)等。
Redis使用场景:
-
热点商品数据缓存
-
消息的订阅/发布(部分场景可取代MQ)
-
各种高频读、低频写的数据场景
-
排行榜、购物车、数据字典
-
快速实现“交并差”运算
3.Redis和memcached和mysql之间的区别
数据库类型 | 数据存储方式 | 特色功能 | |
mysql |
硬盘持久化 传统关系型数据库 |
库表类型存储 每个数据库含有多个表,每个表有很多行数据,以规定的表格形式插入行数据,每个行里面指定数据类型 |
支持ACID性质,主从复制 |
memcached |
内存缓存 传统类型内存缓存,redis出现之前很多公司都会选择的内存工具 |
K/V存储 单一key与value类型存储方式 |
高性能多线程服务器 |
redis |
内存+硬盘持久化 继承了高效缓存的特点,同时兼备成熟的数据持久化方案,现代高效缓存的优秀产品 |
多种数据类型 字符串、列表、集合、散列表、有序集合 |
发布与订阅,主从复制(master/slave)持久化、动态扩容、脚本操作 |
4.Redis和memcached对比
1.memcache数据存储
2.redis数据存储
- 内存管理机制
- Memcached默认使用Slab Allocation机制管理内存,其主要思想就是按照预先规定的大小,将分配的内存分割成特定长度的块,已存储相应长度的key-value数据记录,已完全解决内存碎片问题。空闲列表进行排查存储状态。
-
Redis使用现场申请内存的方式来存储数据,并且很少使用free-list等方式来优化内存分配,会在一定程度上存在内存碎片。
- 数据持久化方案
-
memcached不支持内存数据的持久化操作,所有的数据都以in-memory的形式存储。
-
redis支持持久化操作,redis提供了两种不同的持久化方法来将数据存储到硬盘,第一种是rdb形式,第二种是aof形式。
-
Rdb:将内存进行同步,顾明思义就是内存快照。
-
Aof:append only if,存的是命令,类似set del命令。
-
-
- 缓存数据过期机制
-
memcached:在删除失效主键时采用消极的方法(惰性删除机制),即memcached内部不会监视主键是否失效,而是通过get访问是才会检查其是否已经失效。
-
redis:定时、定期等多种缓存失效机制,减少内存泄漏。
-
- 支持的数据类型
-
memcached支持单一数据类型,[K,V]
-
redis支持5中数据类型
-
5.Redis五种数据结构
5.1 Redis数据结构之:String
5.2 Redis数据结构之:Hash
查看代码
127.0.0.1:6379> hset info name tom
(integer) 1
127.0.0.1:6379> hset info age 20
(integer) 1
127.0.0.1:6379> hset info sex man
(integer) 1
127.0.0.1:6379> hget info sex
"man"
127.0.0.1:6379> hgetall info
1) "name"
2) "tom"
3) "age"
4) "20"
5) "sex"
6) "man"
127.0.0.1:6379>
127.0.0.1:6379> hmset info1 name jack age 10 sex man
OK
127.0.0.1:6379> hgetall info1
1) "name"
2) "jack"
3) "age"
4) "10"
5) "sex"
6) "man"
127.0.0.1:6379>
127.0.0.1:6379> hlen info1
(integer) 3
127.0.0.1:6379> hdel info name
(integer) 1
127.0.0.1:6379> hgetall info
1) "age"
2) "20"
3) "sex"
4) "man"
127.0.0.1:6379>
5.3 Redis数据结构之:list
查看代码
127.0.0.1:6379> lpush newlist one two three
(integer) 3
127.0.0.1:6379> lrange newlist 0 2
1) "three"
2) "two"
3) "one"
127.0.0.1:6379>
127.0.0.1:6379> lpush list value1 value2 value3 value4 value5
(integer) 5
127.0.0.1:6379> lrange list 0 -1
1) "value5"
2) "value4"
3) "value3"
4) "value2"
5) "value1"
127.0.0.1:6379>
127.0.0.1:6379> rpop list
"value98"
127.0.0.1:6379> lrange list 0 -1
1) "value4"
2) "value3"
3) "value2"
4) "value1"
5) "value99"
127.0.0.1:6379>
127.0.0.1:6379> rpush list value99 value98
(integer) 6
127.0.0.1:6379> lrange list 0 -1
1) "value4"
2) "value3"
3) "value2"
4) "value1"
5) "value99"
6) "value98"
127.0.0.1:6379>
127.0.0.1:6379> lpop list
"value5"
127.0.0.1:6379> lrange list 0 -1
1) "value4"
2) "value3"
3) "value2"
4) "value1"
127.0.0.1:6379>
127.0.0.1:6379> llen list
(integer) 5
127.0.0.1:6379> lindex list 2
"value2"
127.0.0.1:6379> lrem list 1 value1
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "value4"
2) "value3"
3) "value2"
4) "value99"
127.0.0.1:6379>
5.4 Redis数据结构之:Set
查看代码
127.0.0.1:6379> sadd myset set1 set2 set3 set4
(integer) 4
127.0.0.1:6379> smembers myset
1) "set4"
2) "set3"
3) "set1"
4) "set2"
127.0.0.1:6379> spop myset 1
1) "set4"
127.0.0.1:6379> smembers myset
1) "set3"
2) "set1"
3) "set2"
127.0.0.1:6379>
127.0.0.1:6379> sadd myset2 set2 set3 set4 set5
(integer) 4
127.0.0.1:6379> smembers myset2
1) "set4"
2) "set3"
3) "set5"
4) "set2"
127.0.0.1:6379> sdiff myset myset2
1) "set1"
127.0.0.1:6379> sunion myset myset2
1) "set5"
2) "set3"
3) "set1"
4) "set4"
5) "set2"
127.0.0.1:6379>
127.0.0.1:6379> sinter myset myset2
1) "set3"
2) "set2"
127.0.0.1:6379>
5.4 Redis数据结构之:SortSet
查看代码
127.0.0.1:6379> sinter myset myset2
1) "set3"
2) "set2"
127.0.0.1:6379> zadd myzset 1 "one" 2 "two" 3 "three"
(integer) 3
127.0.0.1:6379> zrange myzset 0 -1
1) "one"
2) "two"
3) "three"
127.0.0.1:6379> zrem myzset one
(integer) 1
127.0.0.1:6379> zrange myzset 0 -1
1) "two"
2) "three"
127.0.0.1:6379>
6.Redis消息订阅与发布
查看代码
Redis消息发布:
127.0.0.1:6379> PUBLISH channela test
(integer) 0
127.0.0.1:6379> PUBLISH channela redisMessage
(integer) 2
127.0.0.1:6379>
Redis订阅:
127.0.0.1:6379> SUBSCRIBE channela
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channela"
3) (integer) 1
1) "message"
2) "channela"
3) "redisMessage"
Redis订阅:
127.0.0.1:6379> SUBSCRIBE channela
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channela"
3) (integer) 1
1) "message"
2) "channela"
3) "redisMessage"
取消订阅: UNSUBCRIBE channela
7.Redis事务
7.1 事务
一个数据库事务通常包含了一序列对数据库的读/写操作,事务存在包含以下两个目的:
-
为数据库操作序列提供一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态下仍能保持一致的方法。
-
当多个应用程序并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,以防止彼此的操作相互干扰。
7.2 事务的ACID四大特性
-
原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。
-
一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态,即数据库中的数据应满足完整性约束。
-
隔离性(Isolation):多个事务并发执行时,一个事务的执行不影响其他事务的执行。
-
持久性(Durability):以被提交的事务对数据库的修改应该永久保存在数据库中。
事务的隔离机制:
-
语法:set global transaction isolation level read uncommitted;
-
种类:read uncommitted、read committed、read repeatable、serializable
7.2 Redis事务基本命令
-
MULTI与EXEC命令:以MULTI开始一个事务,让后将多个命令入队到事务中,最后由EXEC命令触发事务,一并执行事务中所有的命令。
-
DISCARD命令:DISCARD命令用于取消一个是无,它清空客户端的整个事务队列,然后将客户端从事务状态调整回非事务状态,最后返回字符串 OK 给客户端,说明事务已被取消。
-
WATCH命令:WATCH命令用于在事务开始之前监视任意数量的键,当调用EXEC命令执行事务时,如果任意一个呗监视的键已经被其他客户端修改,那么整个事务不再执行,直接返回失败。
查看代码
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set name tom
QUEUED
127.0.0.1:6379> set age 20
QUEUED
127.0.0.1:6379> get age
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) OK
3) "20"
127.0.0.1:6379> get name
"tom"
127.0.0.1:6379>
WATCH命令:
WATCH命令用于在事务开始之前监视任意数量的键,当调用EXEC命令执行事务时,如果任意一个被监视的键已经被其他客户端修改了,那么整个
事务不在执行,直接返回失败。
127.0.0.1:6379> WATCH message
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set message success
QUEUED
127.0.0.1:6379> get message
QUEUED
127.0.0.1:6379> EXEC
(nil)(返回失败)
127.0.0.1:6379> GET message
"message1"
127.0.0.1:6379>
事务执行之前修改message的值:
127.0.0.1:6379> set message message1
OK
127.0.0.1:6379>
redis事务执行原理图:
7.3 Redis事务与传统关系型事务的比较
-
原子性(Atomicity):单个redis命令执行是原子性的,但是redis没有在事务上增加任何维持原子性的机制,所以redis事务的执行并不是原子的。如果一个事务队列中的所有命令都被成功的执行,那么称这个事务执行成功。
-
一致性(Consistency):
-
入队错误:在命令执行的过程中,如果客户端向服务器发送了错误的命令,比如命令的参数、数量不对等,那么服务器将向客户端返回一个出错信息,并且将客户端的事务状态设置为 REDIS_DITRY_EXEC。
查看代码
127.0.0.1:6379> MULTI OK 127.0.0.1:6379> set age 20 QUEUED 127.0.0.1:6379> get (error) ERR wrong number of arguments for 'get' command 127.0.0.1:6379> get age QUEUED 127.0.0.1:6379> EXEC (error) EXECABORT Transaction discarded because of previous errors. 127.0.0.1:6379>
-
执行错误:如果命令在事务执行的过程中发生错误,例如:对一个不同类型的 key 执行了错误的操作,那么 redis 只会将错误包含在事务的结果中,这不会引起事务中断或整个失败,不会影响已执行事务命令的结果,也不会影响后面要执行的事务命令,所以它对事务的一致性没有影响。
-
-
隔离性(Isolation):WATCH 命令用户在事务开始之前监视任意数量的键,当调用 EXEC 命令执行事务时,如果任意一个被监视的键已经被其他客户端修改,那么整个事务不再执行,直接返回失败。
-
持久性(Durability):因为事务不过是用队列包裹起了一组 redis 命令,并没有提供任何额外的持久性功能,所有事务的持久性由 redis 所使用的持久性模式所决定。Redis持久化模式:
- RDB:数据内存备份
- aof:append only if(增量备份)