redis(二)高级用法

事务

redis的事务是一组命令的集合。事务同命令一样都是redis的最小执行单元,一个事务中的命令要么执行要么都不执行。

首先需要multi命令来开始事务,用exec命令来执行事务。

127.0.0.1:> multi
OK
127.0.0.1:> hset user: name xiaoming
QUEUED
127.0.0.1:> hset user: name daxiong
QUEUED
127.0.0.1:> exec
) (integer)
) (integer)
127.0.0.1:> hgetall user:
) "name"
) "daxiong"
) "score"
) ""
multi代表事务的开始,返回ok表示成功;
 
exec代表事务的执行,返回各个命令的执行结果;
 
在multi和exec中间添加需要执行的命令。
 
在multi开始后,所有命令都不会执行,而是全部暂时保存起来,在执行exec命令后会按照命令保存的顺序依次执行各个命令。
 
如果事务执行过程中存在失败的情况下(某一个命令执行失败后其他命令会继续执行),需要开发人员自行处理后果。
 
注意:redis不支持回滚操作,导致redis的错误异常需要开发人员处理。

watch

watch命令可以监控一个或多个键值的变化,一旦其中一个键被改变,之后的事务就不会执行,而且监控会一直持续到exec命令。
127.0.0.1:> set key
OK
127.0.0.1:> watch key
OK
127.0.0.1:> set key
OK
127.0.0.1:> multi
OK
127.0.0.1:> set key
QUEUED
127.0.0.1:> exec
(nil)
127.0.0.1:> get key
""

生存时间

(1)设置key的超时时间,超时后redis会自动删除给key值,类似于memcache中的超时时间。
 
expire     key     seconds
//设置成功返回1,失败返回0
127.0.0.1:> set session:aabb uid1122
OK
127.0.0.1:> expire session:aabb
(integer)
127.0.0.1:> del session:aabb
(integer)
127.0.0.1:> expire session:aabb
(integer) 127.0.0.1:> expire session:aabb
(integer)
127.0.0.1:> ttl session:aabb
(integer)
(2)查询剩余超时时间
ttl     key
127.0.0.1:> expire session:aabb
(integer)
127.0.0.1:> ttl session:aabb
(integer)
(3)取消超时时间
127.0.0.1:> get session:aabb
""
127.0.0.1:> ttl session:aabb
(integer)
127.0.0.1:> persist session:aabb
(integer)
127.0.0.1:> ttl session:aabb
(integer) -
(4)如果使用设置相关的命令,会取消该键的超时间

缓存数据

在某些情况下,需要缓存一部分网站数据,而网站数据由需要持续的更新(假如需要两个小时更新一次),那么可以采用redis进行缓存这部分数据,设置数据的超时时间为2小时,每当有请求访问的时候首先到redis中查找该数据是否存在,如果存在直接读取,如果不存在的话重新从数据库中读取该数据加载到redis中。
 
在缓存数据的时候需要考虑到被缓存数据的大小,如果缓存数据较大,会占用过多的内存资源,有必要在配置文件中限制内存的使用大小(maxmemory)。
 
当超过maxmemory的限制后,redis会根据maxmemory-policy参数指定的策略(包括LRU等算法)来删除不需要的键。

排序

sort命令支持对集合类型、类表类型、有序集合类型进行排序。
127.0.0.1:> lpush list
(integer)
127.0.0.1:> sort list
) ""
) ""
) ""
) ""
) ""
) ""
) ""
可以对有序集合的值进行排序:
127.0.0.1:> zadd set
(integer)
127.0.0.1:> sort set
) ""
) ""
) ""
) ""
sort命令可以添加desc来实现倒序排序
127.0.0.1:> sort set desc
) ""
) ""
) ""
) ""

BY参数

很多时候我们需要根据ID对应的对象的某一个属性进行排序,那么如何才能把多个不同的数据进行关联查询呢?
(1)首先,向userids中添加三个用户id
127.0.0.1:> lpush userids
(integer)
(2)其次,分别对三个用户添加分数
127.0.0.1:> set user_score_1
OK
127.0.0.1:> set user_score_2
OK
127.0.0.1:> set user_score_3
OK
(3)最后,使用sort、by命令来对对用户按照默认情况以及分数的递增和递减进行排序。

127.0.0.1:> sort userids
) ""
) ""
) ""
127.0.0.1:> sort userids by user_score_*
) ""
) ""
) ""
127.0.0.1:> sort userids by user_score_* desc
) ""
) ""
) ""

GET参数

get参数并不影响排序,它的作用是使sort命令返回的结果不再是元素自身的值,而是get参数中指定的键值,同by参数一样,支持字符串类型和散列类型的键。
127.0.0.1:> sort userids by user_score_* get user_name_*
) "xiaoming"
) "daxiong"
) "xiaohong"
127.0.0.1:> sort userids by user_score_* desc get user_name_*
) "xiaohong"
) "daxiong"
) "xiaoming"

STORE参数

store参数用于结果保存。
 
sort命令是redis的复杂命令之一,使用不好会造成性能的瓶颈。
 
sort命令的时间复杂度是O(n+mlog(m)),其中n是排序列表(集合和有序集合)中元素的个数,m是返回元素的个数。Redis在排序前会建立一个长度为n的的容器来存储待排序元素,虽然是一个临时的过程,但是多个较大数据的排序操作则会严重影响系统的性能。
 
因此,在开发中需要注意:
(1)尽可能减少排序键中的元素个数,降低n
(2)使用Limit参数只获取需要的数据,降低n
(3)如果要排序的数据量较大,尽可能使用store名来缓存结果。

任务队列

任务队列一般适用于生产者和消费者之间通信的,那么在redis中很容易想到使用列表类型来实现任务队列,具体方法是创建一个任务队列,生产者主动lpush数据,而消费者去rpop数据,保持一个先进先出的循序。
但是这样存在一个问题,消费者需要主动去请求数据,周期性的请求会造成资源的浪费,因此,redis提供了一个brpop的命令来解决这个问题。
BRPOP     key     timeout
brpop命令接收两个参数,第一个参数key为键值,第二个参数timeout为超时时间。BRPOP命令取数据时候,如果暂时不存在数据,该命令会一直阻塞直到达到超时时间。如果timeout设置为0,那么就会无限等待下去。

优先级队列

基于任务队列,如何实现优先级队列呢?
 
那么可以选择多个任务队列,而每个任务队列的任务优先级是不同的。
 
redis提供了下面的命令,会从左边第一个key开始读下去知道返回一个数据。
brpop key [key...] timetout

发布/订阅模式

redis提供了rabitmq类似的发布订阅模式,通过生产者使用下面的命令来发布消息,
PUBLISH     CHANNEL     MESSAGE
消费者通过下面的消息来订阅消息,
SUBSCRIBE     CHANNEL     MESSAGE
生产者:
#向channel.test发布消息
127.0.0.1:> publish channel.test hello
(integer) #返回0表明订阅者为0,没有发布消息
127.0.0.1:> publish channel.test hello
(integer) #返回n表明订阅者为n,成功发布给1个消费者
消费者:
#订阅channel.test消息
127.0.0.1:> subscribe channel.test
Reading messages... (press Ctrl-C to quit)
) "subscribe"
) "channel.test"
) (integer)
#接收到来自channel.test的消息
) "message"
) "channel.test"
) "hello"

管道

redis的底层通信协议对管道提供了支持。通过管道可以一次性发送多条命令并在执行完后一次性将结果返回,当一组命令中每条命令都不依赖之前命令的执行结果时就可以将这组命令一起通过管道发出。管道通过减少客户端与redis的通信次数来实现降低往返实验累计值的目的。

节省空间

(1)精简键名和键值
(2)redis为每种数据类型提供了两种内部编码。例如散列类型的存储是通过散列表来实现的,redis会根据数据的多少来选择编码类型,当数据较少的时候会采用紧凑但性能稍差的内部编码方式,而数据变多时会把编码方式改为散列表。

redis(二)高级用法的更多相关文章

  1. sqlalchemy(二)高级用法

    sqlalchemy(二)高级用法 本文将介绍sqlalchemy的高级用法. 外键以及relationship 首先创建数据库,在这里一个user对应多个address,因此需要在address上增 ...

  2. 【iOS开发】Alamofire框架的使用二 高级用法

    Alamofire是在URLSession和URL加载系统的基础上写的.所以,为了更好地学习这个框架,建议先熟悉下列几个底层网络协议栈: URL Loading System Programming ...

  3. sqlalchemy(二)高级用法 2

    转自:https://www.cnblogs.com/coder2012/p/4746941.html 外键以及relationship 首先创建数据库,在这里一个user对应多个address,因此 ...

  4. Redis 一些高级用法

    延迟消息队列 利用 expire keyspace notification Redis 过期时,会向特定的消息队列发送消息,监听该消息队列 在 redis.conf 修改 notify-keyspa ...

  5. C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com

    原文:C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | I ...

  6. redis的Linux系统安装与配置、redis的api使用、高级用法之慢查询、pipline事物

    今日内容概要 redis 的linux安装和配置 redis 的api使用 高级用法之慢查询 pipline事务 内容详细 1.redis 的linux安装和配置 # redis 版本选择问题 -最新 ...

  7. SolrNet高级用法(分页、Facet查询、任意分组)

    前言 如果你在系统中用到了Solr的话,那么肯定会碰到从Solr中反推数据的需求,基于数据库数据生产索引后,那么Solr索引的数据相对准确,在电商需求中经常会碰到菜单.导航分类(比如电脑.PC的话会有 ...

  8. 再谈Newtonsoft.Json高级用法

    上一篇Newtonsoft.Json高级用法发布以后收到挺多回复的,本篇将分享几点挺有用的知识点和最近项目中用到的一个新点进行说明,做为对上篇文章的补充. 阅读目录 动态改变属性序列化名称 枚举值序列 ...

  9. Newtonsoft.Json高级用法(转)

    手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数 ...

随机推荐

  1. java导入excel时遇到的版本问题

    java中读取excel文件时对不同的版本提供了不同的读取方法,这就要求我们在读取excel文件时获取excel文件的版本信息从而通过不同的版本去使用不同的读取方式, 在WorkbookFactory ...

  2. Oracle sys和system用户、sysdba 和sysoper系统权限、sysdba和dba角色的区别

    sys和system用户区别 1)最重要的区别,存储的数据的重要性不同 sys所有oracle的数据字典的基表和视图都存放在sys用户中,这些基表和视图对于oracle的运行是至关重要的,由数据库自己 ...

  3. hdoj 1016 Prime Ring Problem

    Problem Description A ring is compose of n circles as shown in diagram. Put natural number 1, 2, ... ...

  4. paip.语义分析--分词--常见的单音节字词 2_deDuli 单字词 774个

    paip.语义分析--分词--常见的单音节字词 2_deDuli  单字词 774个 作者Attilax  艾龙,  EMAIL:1466519819@qq.com  来源:attilax的专栏 地址 ...

  5. PHP 通过设置P3P头来实现跨域访问COOKIE

    CentOS的系统(Linux 内核) 编辑HOST vi /etc/hosts 加入127.0.0.1 www.a.com127.0.0.1 www.b.com 首先:创建 a_setcookie. ...

  6. S2SH简介

    struts2简介 Struts2是由WebWork基础上发展起来的,与struts1比较,选用struts2的理由是:①Struts1要求Action类继承一个抽象基类,而Struts 2 Acti ...

  7. 【转载】Android数据存储之SQLite

    SQLite是D.Richard Hipp用C语言编写的开源嵌入式数据库引擎.它支持大多数的SQL92标准,并且可以在所有主要的操作系统上运行. 在Android中创建的SQLite数据库存储在:/d ...

  8. python3下安装Django

    1.下载python3 https://www.Python.org/ 我下载的是Python3.5.1 选的 Windows x86-64 executable installer 2. 打开cmd ...

  9. java中FileInputStream和FileOutputStream对图片操作的例子

    package a.ab; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.F ...

  10. 黑马程序员_Java基础:序列化(Serializable)与反序列化

    ------- android培训.java培训.期待与您交流! ---------- 在学习IO中的ObjectOutputStream和ObjectInputStream时,会涉及到序列化和反序列 ...