redis(一)-redis简介

一、简介

Redis是一个速度极快的非关系数据库,也就是我们所说的NoSQL数据库(non-relational database),它可以存储键(key)与5种不同类型的值(value)之间的映射(mapping),可以将存储在内存的键值对数据持久化到硬盘,可以使用复制特性来扩展读性能,还可以使用客户端分片来扩展性能,并且它还提供了多种语言的API。

二、为什么要使用redis

我们想一下下面的问题:

  • redis是key-value的形式,map也是,可以用Map替代redis吗? 
  • 如果不能替代,有什么场景或需求是只有redis能实现的呢?
  • redis 跟其他缓存工具有什么区别呢?

redis VS map

  • Redis 可以用几十 G 内存来做缓存,Map 不行,一般 JVM 也就分几个 G 数据就够大了
  • Redis 的缓存可以持久化,Map 是内存对象,程序一重启数据就没了

  • Redis 可以实现分布式的缓存,Map 只能存在创建它的程序里

  • Redis 可以处理每秒百万级的并发,是专业的缓存服务,Map 只是一个普通的对象

  • Redis 缓存有过期机制,Map 本身无此功能

  • Redis 有丰富的 API,Map 就简单太多了

redis VS memcached

  • Redis和Memcache都是将数据存放在内存中,都是内存数据库。不过memcache还可用于缓存其他东西,例如图片、视频等等;
  • Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储;
  • 虚拟内存--Redis当物理内存用完时,可以将一些很久没用到的value 交换到磁盘;
  • 过期策略--memcache在set时就指定,例如set key1 0 0 8,即永不过期。Redis可以通过例如expire 设定,例如expire name 10;
  • 分布式--设定memcache集群,利用magent做一主多从;redis可以做一主多从。都可以一主一从;
  • 存储数据安全--memcache挂掉后,数据没了;redis可以定期保存到磁盘(持久化);
  • 灾难恢复--memcache挂掉后,数据不可恢复; redis数据丢失后可以通过aof恢复;
  • Redis支持数据的备份,即master-slave模式的数据备份

三、Redis原理

redis作为内存键值对数据库,采用的单线程处理,所以不管怎样都只能使用一个CPU,redis在内存存放数据是采用了hash表实现字典定位数据,字典中key保持唯一,通过对每个key进行hash,再把hash值存放于字典对应的index上,当两个key值发生hash碰撞时,在两个值中间加一个next指针这种链表的方式解决hash碰撞,字典是由两个表组成,ht[0]和ht[1],字典信息都存在ht[0]中,ht[1]在进行rehash时才使用,当hash碰撞率达到阈值或者达到自动调节的阈值时,就会调用rehash使用ht[1]表重新计算key的hash值,收缩hash表或者解决hash碰撞,rehash过程如下:

1) 给ht[1]分配ht[0]的两倍空间

2) 把ht[0]的数据迁移到ht[1]

3) 清空ht[0],将ht[0]指针指向ht[1],将ht[1]指针指向ht[0]

在进行rehash时插入的数据字典信息插入到ht[1],查询、更新、删除同时在ht[0],ht[1]进行,在高并发的插入更新实例上,redis的单线程更利于减少hash碰撞。

四、Redis特性

一个产品的使用场景肯定是需要根据产品的特性,先列举一下Redis的特点:

  • 读写性能优异
  • 持久化
  • 数据类型丰富
  • 单线程
  • 数据自动过期
  • 发布订阅
  • 分布式

五、redis使用场景

1.高性能适合当做缓存

缓存是Redis最常见的应用场景,之所有这么使用,主要是因为Redis读写性能优异。而且逐渐有取代memcached,成为首选服务端缓存的组件。而且,Redis内部是支持事务的,在使用时候能有效保证数据的一致性。
作为缓存使用时,一般有两种方式保存数据:

      1、读取前,先去读Redis,如果没有数据,读取数据库,将数据拉入Redis。

      2、插入数据时,同时写入Redis。

方案一:实施起来简单,但是有两个需要注意的地方:

     1、避免缓存击穿。(数据库没有就需要命中的数据,导致Redis一直没有数据,而一直命中数据库。)

     2、数据的实时性相对会差一点。

方案二:数据实时性强,但是开发时不便于统一处理。

当然,两种方式根据实际情况来适用。如:方案一适用于对于数据实时性要求不是特别高的场景。方案二适用于字典表、数据量不大的数据存储。

2.丰富的数据格式性能更高,应用场景丰富

Redis相比其他缓存,有一个非常大的优势,就是支持多种数据类型。

数据类型 说明
string 字符串,最简单的k-v存储
hash hash格式,value为field和value,适合ID-Detail这样的场景。
list 简单的list,顺序列表,支持首位或者末尾插入数据
set 无序list,查找速度快,适合交集、并集、差集处理
sorted set 有序的set

其实,通过上面的数据类型的特性,基本就能想到合适的应用场景了。

  • string——适合最简单的k-v存储,类似于memcached的存储结构,短信验证码,配置信息等,就用这种类型来存储。
  • hash——一般key为ID或者唯一标示,value对应的就是详情了。如商品详情,个人信息详情,新闻详情等。
  • list——因为list是有序的,比较适合存储一些有序且数据相对固定的数据。如省市区表、字典表等。因为list是有序的,适合根据写入的时间来排序,如:最新的***,消息队列等。
  • set——可以简单的理解为ID-List的模式,如微博中一个人有哪些好友,set最牛的地方在于,可以对两个set提供交集、并集、差集操作。例如:查找两个人共同的好友等。
  • Sorted Set——是set的增强版本,增加了一个score参数,自动会根据score的值进行排序。比较适合类似于top 10等不根据插入的时间来排序的数据。

如上所述,虽然Redis不像关系数据库那么复杂的数据结构,但是,也能适合很多场景,比一般的缓存数据结构要多。了解每种数据结构适合的业务场景,不仅有利于提升开发效率,也能有效利用Redis的性能。

3.单线程可以作为分布式锁

谈到Redis和Memcached 的区别,大家更多的是谈到数据结构和持久化这两个特性,其实还有一个比较大的区别就是:

  • Redis 是单线程,多路复用方式提高处理效率。
  • Memcached 是多线程的,通过CPU线程切换来提高处理效率。

所以Redis单线程的这个特性,其实也是很重要的应用场景,最常用的就是分布式锁。

4.自动过期能有效提升开发效率

Redis针对数据都可以设置过期时间,这个特点也是大家应用比较多的,过期的数据清理无需使用方去关注,所以开发效率也比较高,当然,性能也比较高。最常见的就是:短信验证码、具有时间性的商品展示等。无需像数据库还要去查时间进行对比。因为使用比较简单,就不赘述了。

5.分布式和持久化有效应对海量数据和高并发

Redis初期的版本官方只是支持单机或者简单的主从,大多应用则都是自己去开发集群的中间件,但是随着应用越来越广泛,用户关于分布式的呼声越来越高,所以Redis 3.0版本时候官方加入了分布式的支持,主要是两个方面:

  • Redis服务器主从热备,确保系统稳定性
  • Redis分片应对海量数据和高并发

而且Redis虽然是一个内存缓存,数据存在内存,但是Redis支持多种方式将数据持久化,写入硬盘,所有,Redis数据的稳定性也是非常有保障的,结合Redis的集群方案,有的系统已经将Redis当做一种NoSql数据存储来适用。

猜你喜欢

转载自blog.csdn.net/haoxin963/article/details/83141487