Redis简介

在这里插入图片描述
Redis 概述
在我们日常的Java Web开发中,无不都是使用数据库来进行数据的存储,由于一般的系统任务中通常不会存在高并发的情况,所以这样看起来并没有什么问题,可是一旦涉及大数据量的需求,比如一些商品抢购的情景,或者是主页访问量瞬间较大的时候,单一使用数据库来保存数据的系统会因为面向磁盘,磁盘读/写速度比较慢的问题而存在严重的性能弊端,一瞬间成千上万的请求到来,需要系统在极短的时间内完成成千上万次的读/写操作,这个时候往往不是数据库能够承受的,极其容易造成数据库系统瘫痪,最终导致服务宕机的严重生产问题。

NoSQL 技术
为了克服上述的问题,Java Web项目通常会引入NoSQL技术,这是一种基于内存的数据库,并且提供一定的持久化功能。
Redis和MongoDB是当前使用最广泛的NoSQL,而就Redis技术而言,它的性能十分优越,可以支持每秒十几万此的读/写操作,其性能远超数据库,并且还支持集群、分布式、主从同步等配置,原则上可以无限扩展,让更多的数据存储在内存中,更让人欣慰的是它还支持一定的事务能力,这保证了高并发的场景下数据的安全和一致性。
在这里插入图片描述

什么是 Redis?简述它的优缺点?
Redis 的全称是: Remote Dictionary.Server,本质上是一个 Key-Value 类型的内存数据库,很像
memcached,整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据 flush 到硬盘
上进行保存。
因为是纯内存操作, Redis 的性能非常出色,每秒可以处理超过 10 万次读写操作,是已知性能最快的
Key-Value DB。
Redis 的出色之处不仅仅是性能, Redis 最大的魅力是支持保存多种数据结构,此外单个 value 的最大限
制是 1GB,不像 memcached 只能保存 1MB 的数据,因此 Redis 可以用来实现很多有用的功能。
比方说用他的 List 来做 FIFO 双向链表,实现一个轻量级的高性 能消息队列服务,用他的 Set 可以做高
性能的 tag 系统等等。
另外 Redis 也可以对存入的 Key-Value 设置 expire 时间,因此也可以被当作一 个功能加强版的
memcached 来用。 Redis 的主要缺点是数据库容量受到物理内存的限制,不能用作海量数据的高性能
读写,因此 Redis 适合的场景主要局限在较小数据量的高性能操作和运算上。
Redis 与 memcached 相比有哪些优势?
1.memcached 所有的值均是简单的字符串, redis 作为其替代者,支持更为丰富的数据类型
2.redis 的速度比 memcached 快很多 redis 的速度比 memcached 快很多
3.redis 可以持久化其数据 redis 可以持久化其数据
Redis 支持哪几种数据类型?

1. String操作
String举例:
添加/修改一个 string:
127.0.0.1:6379> set test 123
重新赋值:
127.0.0.1:6379>set test 456
查询一个string:
127.0.0.1:6379>get test
append追加一个string:
127.0.0.1:6379> append test 456
注:(integer) 6(返回字符串的长度)
删除一个key:
127.0.0.1:6379>del test
返回字符串长度
127.0.0.1:6379>strlen test
redis Expire 命令基本语法如下:
redis 127.0.0.1:6379> Expire KEY_NAME TIME_IN_SECONDS
.
查询key的过期时间 ttl
2. hash
·hash是一个string类型的field和value的映射表,可以看做是一个Map表结构容器。
添加一个 hash:
127.0.0.1:6379> HMSET hashtest name xiaoming age 12
返回整个 hash:
127.0.0.1:6379> HGETALL hashtest
1) “name”
2) “xiaoming”
3) “age”
4) “12”
返回hash中的一个字段:
127.0.0.1:6379> hget hashtest name
“xiaoming”
返回hash中的多个个字段:
127.0.0.1:6379> HMGET hashtest name age
1) “xiaoming”
2) “12”
删除一个hash中的字段:
127.0.0.1:6379> HDEL hashtest age
127.0.0.1:6379> HGETALL hashtest
1) “name”
2) “xiaoming”
添加/修改hash中的字段:
127.0.0.1:6379> HSET hashtest name xiaoxin
(integer) 0
127.0.0.1:6379> HGETALL hashtest
1) “name”
2) “xiaoxin”
查看指定键是否存在:
127.0.0.1:6379> HEXISTS hashtest age
(integer) 0
注:返回整数1或0。
1表示哈希包含该字段。
0 表示哈希不包含该字段,或key不存在。

补:
查看所有存在的键:
127.0.0.1:6379> KEYS *  
清空所有数据库数据:  
127.0.0.1:6379> FLUSHALL  
清空当前数据库数据:  
127.0.0.1:6379> FLUSHDB 

3. List
添加元素到列表头:
127.0.0.1:6379> LPUSH listtest a b c
(integer) 4
获取列表指定范围内的元素,LRANGE list_name index_start index_end 如:
127.0.0.1:6379> LRANGE listtest 0 2

  1. “c”
  2. “b”
  3. “a”
    添加元素到列表尾:
    127.0.0.1:6379> RPUSH listtest 1 2 3
    (integer) 6
    查看key对应的value类型:
    127.0.0.1:6379> TYPE listtest
    list
    通过索引获取列表中的值:
    127.0.0.1:6379> LINDEX listtest 3
    “1”
    获取列表长度:
    127.0.0.1:6379> LLEN listtest
    (integer) 6
    移除元素:
    lrem listtest count value
    count > 0 : 从表头开始向表尾搜索,移除与 value 相等的元素,数量为 count 。
    count < 0 : 从表尾开始向表头搜索,移除与 value 相等的元素,数量为 count 的绝对值。
    count = 0 : 移除表中所有与 value 相等的值。
    例子:
    127.0.0.1:6379> LRANGE list 0 2
  4. “3”
  5. “3”
  6. “1”
    127.0.0.1:6379> LREM list 1 3
    (integer) 1
    127.0.0.1:6379> LRANGE list 0 2
  7. “3”
  8. “1”
    删除其中某条记录(示例):
    127.0.0.1:6379> LPUSH list qq ww ee qq qq tt
    (integer) 6
    127.0.0.1:6379> LRANGE list 0 5
  9. “tt”
  10. “qq”
  11. “qq”
  12. “ee”
  13. “ww”
  14. “qq”
    127.0.0.1:6379> LSET list 3 flag
    OK
    127.0.0.1:6379> LRANGE list 0 5
  15. “tt”
  16. “qq”
  17. “qq”
  18. “flag”
  19. “ww”
  20. “qq”
    127.0.0.1:6379> LREM list 0 flag
    (integer) 1
    127.0.0.1:6379>
    4. set
    set是string类型的无序集合。集合成员是唯一的,不允许重复
    添加数据到集合:
    127.0.0.1:6379> SADD settest 1 2 3 4 5
    (integer) 5
    返回集合数据:
    127.0.0.1:6379> SMEMBERS settest
  21. “1”
  22. “2”
  23. “3”
  24. “4”
  25. “5”
    获取集合数量:
    127.0.0.1:6379> SCARD settest
    (integer) 5
    移除集合中的值:
    127.0.0.1:6379> SREM settest 5
    (integer) 1
    5.sorted set(zset)操作
    Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。
    有序集合特点:
    1.有序集合中每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
    2.有序集合的成员是唯一的,但分数(score)却可以重复。
    3.有序集合和集合一样也是string类型元素的集合,且不允许重复的成员
    添加元素到集合:
    127.0.0.1:6379> ZADD sortset 1 a
    (integer) 1
    注:如果value(a)存在,更新分数,否则添加新value,分数可以相同。
    返回指定元素的分数:
    127.0.0.1:6379> ZSCORE sortset a
    “1”
    查询元素,ZRANGE sortset start_index end_index:
    127.0.0.1:6379> ZRANGE sortset 0 1
  26. “a”
    移除集合中的元素:
    127.0.0.1:6379> ZREM sortset a
    (integer) 1
    根据分数区间查询元素
    127.0.0.1:6379> ZCOUNT zset 1 10
    修改score元素
    Redis Zincrby 命令对有序集合中指定成员的分数加上增量 increment
    返回 member 成员的新分数值,以字符串形式表示。
    可以通过传递一个负数值 increment ,让分数减去相应的值,比如 ZINCRBY key -5 member ,就是让 member 的 score 值减去 5 。
    当 key 不存在,或分数不是 key 的成员时, ZINCRBY key increment member 等同于 ZADD key increment member 。
    当 key 不是有序集类型时,返回一个错误。

ZINCRBY key increment member
127.0.0.1:6379> ZINCRBY sorttest 1 a

List、 Set、 Sorted Set、 hashes
Redis 与 memcached的区别

  1. Redis不仅支持简单的k/v类型的数据,同时还支持list、set、zset(sorted set)、hash等数据结构的存储,使得它拥有更广阔的应用场景。

  2. Redis最大的亮点是支持数据持久化,它在运行的时候可以将数据备份在磁盘中,断电或重启后,缓存数据可以再次加载到内存中,只要Redis配置的合理,基本上不会丢失数据,memcache挂掉后,数据没了。

  3. Redis支持主从模式的应用。

  4. Redis单个value的最大限制是512MB,而Memcached则只能保存1MB内的数据。

  5. Memcache在并发场景下,能用cas保证一致性,而Redis事务支持比较弱,只能保证事务中的每个操作连续执行。

  6. 性能方面,根据网友提供的测试,Redis在读操作和写操作上是略领先Memcached的。

  7. Memcached的内存管理不像Redis那么复杂,元数据metadata更小,相对来说额外开销就很少。Memcached唯一支持的数据类型是字符串string,非常适合缓存只读数据,因为字符串不需要额外的处理。

  8. Redis和Memcache都是将数据存放在内存中,都是内存数据库。不过memcache还可用于缓存其他东西,例如图片、视频等等。

  9. 虚拟内存,Redis当物理内存用完时,可以将一些很久没用到的value 交换到磁盘。

  10. 过期策略,memcache在set时就指定,例如set key1 0 0 8,即永不过期。Redis可以通过例如expire 设定,例如expire name 10。

  11. 分布式,设定memcache集群,利用magent做一主多从;redis可以做一主多从。都可以一主一从。

  12. 灾难恢复,memcache挂掉后,数据不可恢复; redis数据丢失后可以通过aof恢复。

  13. Redis支持数据的备份,即master-slave模式的数据备份。

  14. 应用场景不一样,Redis出来作为NoSQL数据库使用外,还能用做消息队列、数据堆栈和数据缓存等;Memcached适合于缓存SQL语句、数据集、用户临时性数据、延迟查询数据和session等;Redis适合数据量较小的更性能操作和运算上Memcache用于在动态系统中减少数据库负载,提升性能;做缓存,提高性能(适合读多写少,对于数据量比较大,可以采用sharding)
    Redis的单线程理解

Redis客户端对服务端的每次调用都经历了发送命令,执行命令,返回结果三个过程。其中执行命令阶段,由于Redis是单线程来处理命令的,所有到达服务端的命令都不会立刻执行,所有的命令都会进入一个队列中,然后逐个执行,并且多个客户端发送的命令的执行顺序是不确定的,但是可以确定的是不会有两条命令被同时执行,不会产生并发问题,这就是Redis的单线程基本模型。

Redis服务器通过socket(套接字)与客户端或其他Redis服务器进行连接,而文件事件就是服务器对socket操作的抽象。服务器与客户端或其他服务器的通信会产生相应的文件事件,而服务器通过监听并处理这些事件来完成一系列网络通信操作。

Redis基于Reactor模式开发了自己的网络事件处理器——文件事件处理器,文件事件处理器使用I/O多路复用程序来同时监听多个socket(I/O多路复用技术下面有介绍),并根据socket目前执行的任务来为socket关联不同的事件处理器。当被监听的socket准备好执行连接应答、读取、写入、关闭等操作时,与操作相对应的文件事件就会产生,这时文件事件处理器就会调用socket之前已关联好的事件处理器来处理这些事件。
文件事件处理器的构成:
在这里插入图片描述
Redis的单线程为什么这么快?

1.完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);

2.数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的;

3.采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;

4.使用多路I/O复用模型,非阻塞I/O;

5.Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;

为什么不采用多进程或多线程处理?

1.多线程处理可能涉及到锁

2.多线程处理会涉及到线程切换而消耗CPU

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值