Redis应用总结

首先, 我带大家简单的了解一下Redis

Redis常用数据类型(最为常用的数据类型主要有以下五种)

●String

●Hash

●List

●Set

●Sorted set

下面我们先来逐一的分析下这五种数据类型的使用和内部实现方式:

1、String

常用命令:

set,get,decr,incr,mget 等。

常用方法:

set -- 设置key对应的的值为String类型的value

get -- 获取对应key对应的String的值,如果不存在返回nil

setnx -- 设置可以为对应的值为String类型的value,如果key存在返回0不覆盖,不存在返回1

setex -- 置key对应的值为String类型的value,并指定此键值对应的有效期

SETEX key seconds value

例:setex mykey 10 你好

setrange -- 设置key的value的子字符串

setrange -- key 位置 替换的内容如果替换内容没有原value长,则原value剩余的内容将被保留

mset -- 一次设置多个key的值,成功返回ok,失败返回0,要成功都成功,要不成功全部失 败。

例:mset key1 内容一 key2 内容二

msetnx -- 一次设置多个key的值,成功返回ok,失败返回0,不覆盖已经存在的值,要成功都 成功,要失败都失败。

getset -- 设置key的值并返回key的旧值

例:getset key newValuse

getrange -- 获取key对应的value子字符串

例:getrange key 0 5 //获取前6个字符

mget -- 批量获取

例:mget key1 key2 key3 //没有设置则返回空

incr -- 对key的值做增加操作,并返回新的值

incrby -- 对可以的value加指定的值,key如果不存在会设置key并value为0

例:incrby key1 5 //对key1的值加5

decr -- 对key的值做减减操作-1

decrby -- 对key的值减去指定值

append -- 给指定key的字符串追加value,返回新的字符串长度

strlen -- 取指定key的value值的长度

应用场景:

String是最常用的一种数据类型,普通的key/value存储都可以归为此类,value其实不仅是String,也可以是数字。比如想知道什么时候封锁一个IP地址(访问超过几次)。incrby命令让这些变得很容易,通过原子递增保持计数。常规计数: 微博数, 粉丝数

Hashs

在Memcached中,我们经常将一些结构化的信息打包成hashmap,在客户端序列化后存储为一个字符串的值,比如用户的昵称、年龄、性别、积分等,这时候在需要修改其中某一项时,通常需要将所有值取出反序列化后,修改某一项的值,再序列化存储回去。这样不仅增大了开销,也不适用于一些可能并发操作的场合(比如两个并发的操作都需要修改积分)。而Redis的Hash结构可以使你像在数据库中Update一个属性一样只修改某一项属性值。它是一个String类型的field和value的映射表,它的添加和删除都是平均的,hash特别适合用于存储对象,对于将对象存储成字符串而言,hash会占用更少的内存,并且可以更方便的存取整个对象. 它和java的HashMap完全类似

常用命令:

hget,hset,hgetall 等。

常用方法:

hset -- 设置一个hash 的field为指定值,如果key不存在则先创建

例:hset tab ke1 val1

hget -- 获取某个hash的某个field值

例:hget tab ke1

hsetnx -- 类似string只是操作的是hash

hmset -- 批量设置hash的内容

hmget -- 获取hash表的全部key值

例:Hmget key field1 field2

hincrby -- 给hash表的某个字段增加值

hexists -- 判断hash表中某个key是否存在

hlen -- 返回hash表中的key数量

hdel -- 删除指定hash表的某个键值对

hkeys -- 返回hash表中所有的key

hvals -- 返回hash表中所有的value

hgetall -- 获取hash表中所有key和value

使用场景:

存储部分变更数据。如用户信息等。

Lists

Lists 就是链表,略有数据结构知识的人都应该能理解其结构。使用Lists结构,我们可以轻松地实现最新消息排行等功能。Lists的另一个应用就是消息队列,可以利用Lists的PUSH操作,将任务存在Lists中,然后工作线程再用POP操作将任务取出进行执行。Redis还提供了操作Lists中某一段的api,你可以直接查询,删除Lists中某一段的元素。Redis的list是每个子元素都是String类型的双向链表,可以通过push和pop操作从列表的头部或者尾部添加或者删除元素,这样List即可以作为栈,也可以作为队列。

Redis list的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,Redis内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构。

常用命令:

lpush,rpush,lpop,rpop,lrange等。

常用方法:

lpush -- 在key所对应的list头部添加一个元素 ==》l的意思是left

rpush -- 在key说对应的list尾部添加一个元素 ==》r的意思是right

lrange -- 显示list里面的内容

例:lrange 0 -1 //全部显示

linsert -- 在key对应的list

例:linsert mylist before one myvalue

lset -- 设置list中指定下标元素的值

例:lset mylist index myvalue

lrem -- 从key对应的list中删除n个和value相同的元素,结果返回影响元素的个数,n<0从尾部开 始删除,n=0全删除

例:lrem mylist count "value"

ltrim -- 保留指定key范围内的数据,返回ok成功

例:ltrim mylist 0 3 //0-3是保留的范围

lpop -- 从list的头部删除一个元素,并返回该删除的元素

rpop -- 从list的尾部弹出一个元素,并返回该删除的元素

rpoplpush -- 从第一个list的尾部元素异常元素并添加到第二个list的头部

例:rpoplpush mylistA mylistB

lindex -- 返回list位置的元素

例:lindex mylist 3

llen -- 返回list中元素的个数

例:llen mylist

使用场景

消息队列系统

使用list可以构建队列系统,使用sorted set甚至可以构建有优先级的队列系统。

比如:将Redis用作日志收集器

实际上还是一个队列,多个端点将日志信息写入Redis,然后一个worker统一将所有日志写到磁盘。

Set

常用命令:

sadd,spop,smembers,sunion 等。

实现方式:

set 的内部实现是一个 value永远为null的HashMap,实际就是通过计算hash的方式来快速排重的,这也是set能提供判断一个成员是否在集合内的原因。set中的元素是没有顺序的。

常用方法:

sadd -- 向名称为key的set中添加元素,返回影响元素的个数,0为失败,1为成功

例:sadd myset value

smembers -- 查看集合中所有的成员

例:smebers myset

srem -- 删除集合的一个元素

例:srem myset two

spop -- 随机返回并删除set中一个元素

例:spop myset

sdiff -- 返回所有set与第一个set的差集

例:sdiff myset1 myset2

sdiffstore -- 比较差集并且存储到另一个set中,返回1代表成功

例:sdiffstore setstoreSet mySet1 myset2

sinter -- 返回所有给定集合的交集

例:sinter myset1 mysert2 //1集合和2集合的交集

sinterstore -- 返回给定集合的交集并存储到另一个集合

例:sinterstore desset myset1 myset2 //存到desset集合中

sunion -- 返回所有给定集合的并集

例:sunion set1 set2

sunionstore -- 返回所有的并集并且存储到另一个集合中,返回影响的元素个数

例:sunionstore destSet myset1 myset2

smove --把第一个集合的元素移动到第二个集合中

例:smove myset myset 你好

scard -- 返回集合中元素的个数

例:scard myset1

sismember --测试某个元素是否在集合中,返回0是不是,大于0是存在

例:sismember mykey1 你好

srandmember -- 随机返回个集合中的元素

例:srandmemeber myset1

应用场景:

Redis set对外提供的功能与list类似是一个列表的功能,特殊之处在于set是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。

Sorted Sets

常用命令:

zadd,zrange,zrem,zcard等

实现方式:

Redis sorted set的内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,而跳跃表里存放的是所有的成员,排序依据是HashMap里存的score,使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单。

常用方法:

zadd -- 向zset中添加元素member,score 用于排序,如果元素存在,则更新其顺序,返回0代 表没添加成功

例:ZADD key score member

zadd myset 3 itim

zrange -- 取出集合中的元素

例:zrange myset 0 -1 withscores//显示序号

zrem -- 删除名称为key的zset中的元素member

例:zrem myset itim

zincrby -- 修改元素的排序,如果元素不存在则添加该元素,且排序的score值为增加值

例:zincrby myzset score itim

zrank -- 返回元素在集合中的排序位置,就是索引值

例:zrank myzset itim //itim在集合中的位置

zrevrank -- 返回从大到小的排序索引值,就是逆序位置

例:zrevrangk myzset itim//逆序的位置

zrevrange -- 返回集合中从大到小排序(降序)的,索引start到end的所有元素

例:zrevrange myzset 0 -1 //逆序后的元素

zrangebyscore -- 根据排序索引的scores来返回元素

例:zrangebyscore myzset 1 3 withscores//

zcount -- 返回集合中给定区间的数量

例:zcount myzset 2 4 //集合中2-4索引元素的个数

zcard -- 返回集合中所有元素的个数

例:zcard myzset //返回所有元素的个数

zremrangebyrank -- 删除集合中排序在给定区间的所有元素(按索引删除)

例:zremrangebyrank myzset 2 3 //

zremrangebyscore -- 删除集合中在给定排序区间的元素 (按顺序删除)

例:zremrangebyscore myzset 2 5 //

使用场景:

Redis sorted set的使用场景与set类似,区别是set不是自动有序的,而sorted set可以通过用户额外提供一个优先级(score)的参数来为成员排序,并且是插入有序的,即自动排序。当你需要一个有序的并且不重复的集合列表,那么可以选择sorted set数据结构。

和Sets相比,Sorted Sets增加了一个权重参数score,使得集合中的元素能够按score进行有序排列,比如一个存储全班同学成绩的Sorted Sets,其集合value可以是同学的学号,而score就可以是其考试得分,这样在数据插入集合的时候,就已经进行了天然的排序。可以用Sorted Sets来做带权重的队列,比如普通消息的score为1,重要消息的score为2,然后工作线程可以选择按score的倒序来获取工作任务。让重要的任务优先执行。

总结:

1.根据业务需要选择合适的数据类型,并为不同的应用场景设置相应的紧凑存储参数。

2.当业务场景不需要数据持久化时,关闭所有的持久化方式可以获得最佳的性能以及最大的内存使用量。

3.如果需要使用持久化,根据是否可以容忍重启丢失部分数据在快照方式与语句追加方式之间选择其一,不要使用虚拟内存以及diskstore方式。

4.不要让你的Redis所在机器物理内存使用超过实际内存总量的3/5。

原文发布于微信公众号 - 高性能服务器开发(easyserverdev)

原文发表时间:2018-02-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏coding for love

JS入门难点解析8-作用域,作用域链,执行上下文,执行上下文栈等分析

(注1:如果有问题欢迎留言探讨,一起学习!转载请注明出处,喜欢可以点个赞哦!) (注2:更多内容请查看我的目录。)

12210
来自专栏JavaEdge

HotSPot虚拟机对象探秘1 对象的创建过程2 对象的内存布局3 访问对象的过程

402160
来自专栏电光石火

null或空值的判断处理

1,错误用法一: if (name == "") {      //do something } 2,错误用法二: if (name.equal...

23090
来自专栏达摩兵的技术空间

es6入门

es6作为最新的js语言版本,有很多特性是不得不晓的。下面将语法中常用的分析出来,对应到基本对象类型的会在对象里描述。

5310
来自专栏技术小站

编程填空:第i位替换 编程填空:第i位取反 编程填空:左边i位取反

写出函数中缺失的部分,使得函数返回值为一个整数,该整数的第i位和m的第i位相同,其他位和n相同。

24210
来自专栏java学习

Java每日一练(2017/7/7)

1 (单选题)有以下程序片段,下列哪个选项不能插入到行 1 。()。 1. 2.public class A{ 3.//do sth 4. } A publ...

398110
来自专栏程序员互动联盟

【编程基础第十一讲】代码如何写才最漂亮第一篇

存在问题: 好多小伙伴对编码的格式作用模糊,以为只要完成功能就行,其实这种观点是错误的,一定要重视代码规范,不然你哭的地都找不到。 如何实施: 良好的代码开发习...

28470
来自专栏Python攻城狮

Python数据科学(二)- python与数据科学应用(Ⅱ)1.Python3 语法之for循环、if分支语句2.函数3.导入模块4.Jupyter notebook内代码的保存与分享5.数据科学实

使用Jupyter notebook文档写好之后, 保存成为一般的.ipynb的格式, 但是也可以保存成其他的格式, 如: Python(.py), Markd...

9320
来自专栏Golang语言社区

Golang语言的函数调用信息

函数的调用信息是程序中比较重要运行期信息, 在很多场合都会用到(比如调试或日志). Go语言 runtime 包的 runtime.Caller / runti...

58960
来自专栏C/C++基础

将模板申明为友元

严格来说,函数模板(类模板)是不能作为一个类的友元的,就像类模板之间不能发生继承关系一样。只有当函数模板(或类模板)被实例化之后生成模板函数(或模板类),该函数...

10510

扫码关注云+社区

领取腾讯云代金券