redis学习笔记

redis是一个功能强大的内存数据结构存储,具备多种用途,包括数据库,缓存。html

github上有人整理里一份很全面的redis学习文档。java

1. redis特性

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

1.1 高性能适合当作缓存git

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

  • 一、读取前,先去读Redis,若是没有数据,读取数据库,将数据拉入Redis。
  • 二、插入数据时,同时写入Redis。

方案一:实施起来简单,可是有两个须要注意的地方:
一、避免缓存击穿。(数据库没有就须要命中的数据,致使Redis一直没有数据,而一直命中数据库。)
二、数据的实时性相对会差一点。redis

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

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

1.2 丰富的数据格式性能更高,应用场景丰富缓存

Redis相比其余缓存,有一个很是大的优点,就是支持多种数据类型。安全

数据类型说明string字符串,最简单的k-v存储hashhash格式,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的性能。

1.3 单线程能够做为分布式锁

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

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

因此Redis单线程的这个特性,其实也是很重要的应用场景,最经常使用的就是分布式锁。
应对高并发的系统,都是用多服务器部署,每一个技术框架针对数据锁都有很好的处理方式,如 .net 的lock,java 的synchronized,都能经过锁住某个对象来应对线程致使的数据污染问题。可是毕竟,只能控制本服务器的线程,分布式部署之后数据污染问题,就比较难处理了。Redis的单线程这个特性,就很是符合这个需求,伪代码以下:

//产生锁
while lock!=1
    //过时时间是为了不死锁
    now = int(time.time())
    lock_timeout = now + LOCK_TIMEOUT + 1
    lock = redis_client.setnx(lock_key, lock_timeout)

//真正要处理的业务
doing() 

//释放锁
now = int(time.time())
if now < lock_timeout:
    redis_client.delete(lock_key)

以上是一个只说明流程的伪代码,其实总体的逻辑是很简单的,只要考虑到死锁时的状况,就比较好处理了。Redis做为分布式锁,由于其性能的优点,不会成为瓶颈,通常会产生瓶颈的是真正的业务处理内容,仍是尽可能缩小锁的范围来确保系统性能。

1.4 自动过时能有效提高开发效率

Redis针对数据均可以设置过时时间,这个特色也是你们应用比较多的,过时的数据清理无需使用方去关注,因此开发效率也比较高,固然,性能也比较高。最多见的就是:短信验证码、具备时间性的商品展现等。无需像数据库还要去查时间进行对比。由于使用比较简单,就不赘述了

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

Redis初期的版本官方只是支持单机或者简单的主从,大多应用则都是本身去开发集群的中间件,可是随着应用愈来愈普遍,用户关于分布式的呼声愈来愈高,因此Redis 3.0版本时候官方加入了分布式的支持,主要是两个方面:

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

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

1.6 示例:秒杀和Redis的结合

秒杀是如今互联网系统中常见的营销模式,做为开发者,其实最不肯意这样的活动,由于非技术人员没法理解到其中的技术难度,致使在资源协调上老是有些误差。秒杀其实常常会出现的问题包括:

  • 并发过高致使程序阻塞。
  • 库存没法有效控制,出现超卖的状况。

其实解决这些问题基本就两个方案:

  • 数据尽可能缓存,阻断用户和数据库的直接交互。
  • 经过锁来控制避免超卖现象。

如今说明一下,若是如今作一个秒杀,那么,Redis应该如何结合进行使用?

  • 提早预热数据,放入Redis
  • 商品列表放入Redis List
  • 商品的详情数据 Redis hash保存,设置过时时间
  • 商品的库存数据Redis sorted set保存
  • 用户的地址信息Redis set保存
  • 订单产生扣库存经过Redis制造分布式锁,库存同步扣除
  • 订单产生后发货的数据,产生Redis list,经过消息队列处理
  • 秒杀结束后,再把Redis数据和数据库进行同步

2. 大多数人常常认为它是一个简单的键值存储,但它拥有不少强大的功能。

2.1 整页缓存

使用服务器端渲染页面,若是不但愿为每一个请求从新渲染页面。可使用 redis 将其缓存起来,能够大大减小请求页面的延迟。

// Set the page that will last 1 minute
SET key "<html>...</html>" EX 60

// Get the page
GET key

2.2 排行榜

redis 在内存中能够很是快速和高效地处理递增和递减。比起为每一个请求执行一次 SQL 查询它能够给应用节省不少的时间!

使用 redis 的 sortedset 你能够以毫秒为单位抓取列表中评分最高的项目,并且用起来很是的简单。

// Add an item to the sorted set
ZADD sortedSet 1 "one"

// Get all items from the sorted set
ZRANGE sortedSet 0 -1

// Get all items from the sorted set with their score
ZRANGE sortedSet 0 -1 WITHSCORES

2.3 Session 存储

咱们一般会使用 redis 来储存 session,和其余的缓存系统不一样(例如Memcache),redis 能够持久化储存 session,这样就算服务器出故障这些 session 也不会丢失。

// Set session that will last 1 minute
SET randomHash "{userId}" EX 60

// Get userId
GET randomHash

2.4 队列

一个不太常见但很是有用的是你能够用 redis 建立队列,不管是电子邮件仍是应用程序使用的其余数据,均可以使用 redis 来建立一个高效的队列。

// Add a Message
HSET messages <id> <message>
ZADD due <due_timestamp> <id>

// Recieving Message
ZRANGEBYSCORE due -inf <current_timestamp> LIMIT 0 1
HGET messages <message_id>

// Delete  Message
ZREM due <message_id>
HDEL messages <message_id>

2.5 Pub/Sub

Pub/Sub 能够用在不少的地方。你能够用来建立一个实时聊天系统,触发社交网络上的朋友请求通知等等。这个功能是 redis 提供的最被低估的功能之一。

// Add a message to a channel
PUBLISH channel message

// Recieve messages from a channel
SUBSCRIBE channel

 3. redis数据类型及基本操做

 redis共有五种数据类型。

1).String 能够是字符串、整数或浮点,统称为元素

string是redis最基本的类型,你能够理解成与Memcached如出一辙的类型,一个key对应一个value。

string类型是二进制安全的。意思是redis的string能够包含任何数据。好比jpg图片或者序列化的对象 。

string类型是Redis最基本的数据类型,一个键最大能存储512MB。

redis 127.0.0.1:6379> SET name "runoob" OK redis 127.0.0.1:6379> GET name "runoob"

2).list 一个序列集合且每一个节点都包好了一个元素

Redis 列表是简单的字符串列表,按照插入顺序排序。你能够添加一个元素到列表的头部(左边)或者尾部(右边)。

redis 127.0.0.1:6379> lpush runoob redis (integer) 1 redis 127.0.0.1:6379> lpush runoob mongodb (integer) 2 redis 127.0.0.1:6379> lpush runoob rabitmq (integer) 3 redis 127.0.0.1:6379> lrange runoob 0 10 1) "rabitmq" 2) "mongodb" 3) "redis"

3).Set 各不相同的元素

Redis的Set是string类型的无序集合。

集合是经过哈希表实现的,因此添加,删除,查找的复杂度都是O(1)。

sadd 命令

sadd key member

添加一个 string 元素到 key 对应的 set 集合中,成功返回1,若是元素已经在集合中返回 0,若是 key 对应的 set 不存在则返回错误。

redis 127.0.0.1:6379> sadd runoob redis (integer) 1 redis 127.0.0.1:6379> sadd runoob mongodb (integer) 1 redis 127.0.0.1:6379> sadd runoob rabitmq (integer) 1 redis 127.0.0.1:6379> sadd runoob rabitmq (integer) 0 redis 127.0.0.1:6379> smembers runoob 1) "redis" 2) "rabitmq" 3) "mongodb"

 

4).Hash 有key-value的散列组,其中key是字符串,value是元素

Redis hash 是一个键值(key=>value)对集合。

Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象

redis> HMSET myhash field1 "Hello" field2 "World" "OK" redis> HGET myhash field1 "Hello" redis> HGET myhash field2 "World"

 

5).zsetSort-Set 带分数的score-value有序集合,其中score为浮点,value为元素

 Redis zset 和 set 同样也是string类型元素的集合,且不容许重复的成员。

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

zset的成员是惟一的,但分数(score)却能够重复。

zadd key score member 

zadd 命令

添加元素到集合,元素在集合中存在则更新对应score

redis 127.0.0.1:6379> zadd runoob 0 redis (integer) 1 redis 127.0.0.1:6379> zadd runoob 0 mongodb (integer) 1 redis 127.0.0.1:6379> zadd runoob 0 rabitmq (integer) 1 redis 127.0.0.1:6379> zadd runoob 0 rabitmq (integer) 0 redis 127.0.0.1:6379> > ZRANGEBYSCORE runoob 0 1000 1) "mongodb" 2) "rabitmq" 3) "redis"
相关文章
相关标签/搜索