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事务基本命令

  1. MULTIEXEC命令:以MULTI开始一个事务,让后将多个命令入队到事务中,最后由EXEC命令触发事务,一并执行事务中所有的命令。

  2. DISCARD命令:DISCARD命令用于取消一个是无,它清空客户端的整个事务队列,然后将客户端从事务状态调整回非事务状态,最后返回字符串 OK 给客户端,说明事务已被取消。

  3. 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(增量备份)

 

posted @ 2022-03-03 09:22  BlogMemory  阅读(67)  评论(0编辑  收藏  举报