Redis学习——数据结构上

一、常用的全局命令

1、查看所有的键: KEYS *

KEYS pattern:查找所有符合给定模式 pattern 的 key 。

KEYS 的速度非常快,但在一个大的数据库中使用它仍然可能造成性能问题,如果你需要从一个数据集中查找特定的 key ,你最好还是用 Redis 的集合结构(set)来代替。

时间复杂度:O(N), N 为数据库中 key 的数量。

2、键总数:dbsize(返回当前数据库中键的总数)

3、检查建是否存在 exists key

4、删除键:del key[...]:del是一个通用命令,无论什么数据结构类型,del命令都可以将他删除。

同时del命令支持删除多个键del a b c(同事删除a b c 三个键)

5、键过期:expire key seconds

ttl命令会返回键的剩余过期时间,它有三种返回值:大于0的整数(键剩余的过期时间),-1(键没设置过期时间),-2:键不存在

6、键的数据结构类型:type key

二、数据结构和内部编码

redis对外的数据结构有五种:string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合)

这些只是redis对外的数据结构,实际上每种数据结构都有自己的底层的内部编码实现,而且是多种实现。例如LIST包含了linklist和ziplist两种内部编码。用object encoding key 能查询内部编码

1)、字符串

字符串类型是redis最基础的数据结构。字符串的值不能超过512M.

字符串常用命令

1、设置值: set key value

set rdb 123 :设置一个键rdb,值为123

set rdb 123 ex 10:设置一个键rdb,值为123,过期时间为10秒

set rdb 123 px 10:设置一个键rdb,值为123,过期时间为10毫秒

setex rdb 10 123: 设置一个键rdb,值为123,过期时间为10秒

set rdb 1 xx:将键rdb的值更新为1

set rdb 123 nx:设置一个键rdb,值为123

setnx rdb 123:设置一个键rdb,值为123

说明:setex和setnx两个命令作用和ex和nx选项是一样的。

setnx和set的区别:由于redis的单线程命令处理机制,如果有多个客户端同时执行setnx key value,根据setnx的特性只有一个客户端能设置成功,setnx可以作为分布式锁的一种

实现方案,Redis官方给出了使用setnx实现分布式锁的方法:http://redis.io/topics/distlock。

2、获取值:get key

如果获取的键不存在,则返回nil(空)

3、批量设置值

mset key value [key value]

mset a 1 b 2 c 3 d 4:设置了4个键值对

4、批量获取值

mget key [key ...]

mget a b c d

批量操作命令可以有效提高开发效率

5、计数

incr命令用于对值做自增操作,返回结果分为三种情况

1、值不是整数,返回错误

2、值是整数,返回自增后的结果

3、键不存在,按照值为0自增,返回结果为1

不常用的命令:

1、追加值 append key value(append可以向字符串尾部追加值)

2、字符串长度  strlen key(每个中文占3个字节)

3、设置并返回原值(getset和set一样会设置值,但是不同的是,它同时会返回键原来的值)

4、设置指定位置的字符 setrange key offeset value

set redis pest

setrange redis 0 b :将pest变成best

5、获取部分字符串 getrange key start end

set redis best

getrange redis 0 1:返回be

内部编码:字符串类型的内部编码有3种

.int:8个字节的长整型。

·embstr:小于等于39个字节的字符串。

·raw:大于39个字节的字符串。

(Redis会根据当前值的类型和长度决定使用哪种内部编码实现。)

redis字符串的典型使用场景:

1、缓存功能

与MySQL等关系型数据库不同的是,Redis没有命令空间,而且也没有对键名有强制要求(除了不能使用一些特殊字符)。但设计合理的键名,有利于防止键冲突和项目的可维护性,

比较推荐的方式是使用“业务名:对象名:id:[属性]”作为键名(也可以不是分号)。

2、计数功能

许多应用都会使用Redis作为计数的基础工具,它可以实现快速计数、查询缓存的功能,同时数据可以异步落地到其他数据源。

3、共享Session

可以使用Redis将用户的Session进行集中管理,在这种模式下只要保证Redis是高可用和扩展性的,每次用户更新或者查询登录信息都直接从Redis中集中获取。

4、限速

很多应用出于安全的考虑,会在每次进行登录时,让用户输入手机验证码,从而确定是否是用户本人。但是为了短信接口不被频繁访问,会限制用户每分钟获取验证码的频率,例如一分钟不能超过5次。

2、哈希

几乎所有的编程语言都提供了哈希(hash)类型,它们的叫法可能是哈希、字典、关联数组。在Redis中,哈希类型是指键值本身又是一个键值对结构,形如value={{field1,value1},...{fieldN,valueN}}

注意(哈希类型中的映射关系叫作field-value,注意这里的value是指field对应的值,不是键对应的值,请注意value在不同上下文的作用)

常用命令:

1、设置值 hset key field value

hset user:1 name tom:设置键为user:1 ,filed为name,value为tom。

2、获取值 hget key field

hget user:1 name  :返回tom

3、删除field hdel key field [field ...]

hdel user:1 name

4、计算field个数

hlen key

5、批量设置或获取field-value

hmget key field [field ...]

hmset key field value [field value ...]

6、判断field是否存在 hexists key field

7、获取所有field: hkeys key

8、获取所有value:hvals key

9、获取所有的field-value:hgetall key

(注意:在使用hgetall时,如果哈希元素个数比较多,会存在阻塞Redis的可能。如果开发人员只需要获取部分field,可以使用hmget,如果一定要获取全部field-value,可以使用hscan命令,该命令会渐进式遍历哈希类型)

10、hincrby hincrbyfloat

11、计算value的字符串长度 hstrlen key field

内部编码(哈希类型的内部编码有两种)

·ziplist(压缩列表):当哈希类型元素个数小于hash-max-ziplist-entries配置(默认512个)、同时所有值都小于hash-max-ziplist-value配置(默认64字节)时,Redis会使用ziplist作为哈希的内部实现,ziplist使用更加紧凑的结构实现多个元素的连续存储,所以在节省内存方面比hashtable更加优秀

·hashtable(哈希表):当哈希类型无法满足ziplist的条件时,Redis会使用hashtable作为哈希的内部实现,因为此时ziplist的读写效率会下降,而hashtable的读写时间复杂度为O(1)。

使用场景:1、存储关系数据库数据

相比于使用字符串序列化缓存用户信息,哈希类型变得更加直观,并且在更新操作上会更加便捷。可以将每个用户的id定义为键后缀,多对field-value对应每个用户的属性

(但是需要注意的是哈希类型和关系型数据库有两点不同之处:·哈希类型是稀疏的,而关系型数据库是完全结构化的,例如哈希类型

每个键可以有不同的field,而关系型数据库一旦添加新的列,所有行都要为其设置值(即使为NULL)

·关系型数据库可以做复杂的关系查询,而Redis去模拟关系型复杂查询开发困难,维护成本高。

(比较说明名:到目前为止,我们已经能够用三种方法缓存用户信息,下面给出三种方案的实现方法和优缺点分析。

1、原生字符串类型:每个属性一个键。

set user:1:name tom

set user:1:age 23

set user:1:city beijing

优点:简单直观,每个属性都支持更新操作。

缺点:占用过多的键,内存占用量较大,同时用户信息内聚性比较差,所以此种方案一般不会在生产环境使用。

2、序列化字符串类型:将用户信息序列化后用一个键保存。

set user:1 serialize(userInfo)

优点:简化编程,如果合理的使用序列化可以提高内存的使用效率。

缺点:序列化和反序列化有一定的开销,同时每次更新属性都需要把全部数据取出进行反序列化,更新后再序列化到Redis中。

3、哈希类型:每个用户属性使用一对field-value,但是只用一个键保存。

hmset user:1 name tomage 23 city beijing

优点:简单直观,如果使用合理可以减少内存空间的使用。

缺点:要控制哈希在ziplist和hashtable两种内部编码的转换,hashtable会消耗更多内存。

3、列表List(列表(list)类型是用来存储多个有序的字符串)

在Redis中,可以对列表两端插入(push)和弹出(pop),还可以获取指定范围的元素列表、获取指定索引下标的元素等。列表是一种比较灵活的数据结构,它可以充当栈和队列的角色,在实际开发上有很多应用场景。

1、列表的两个特点

.列表中的元素是有序的

.列表中的元素可以是重复的

2、命令

1、添加操作

·从右边插入元素 rpush key value [value ...](lrange 0 -1命令可以从左到右获取列表的所有元素)

·从左边插入元素 lpush key value [value ...]

·向某个元素前或者后插入元素  linsert key before|after pivot value (linsert命令会从列表中找到等于pivot的元素,在其前(before)或者后(after)插入一个新的元素value)

2、查找

·获取指定范围内的元素列表 lrange key start end (lrange操作会获取列表指定索引范围所有的元素)

索引下标有两个特点:1、索引下标从左到右分别是0到N-1,但是从右到左分别是-1到-N

2、lrange中的end选项包含了自身

·获取列表指定索引下标的元素 lindex key index:例如 lindex listkey -1

·获取列表长度 llen key

3、删除

·从列表左侧弹出元素 lpop key

·从列表右侧弹出 rpop key

·删除指定元素 lrem key count value

lrem命令会从列表中找到等于value的元素进行删除,根据count的不同分为三种情况:

·count>0,从左到右,删除最多count个元素。

·count<0,从右到左,删除最多count绝对值个元素。

·count=0,删除所有。

·按照索引范围修剪列表 ltrim key start end

ltrim listkey 1 3 (只保留列表listkey第2个到第4个元素)

4、修改

·修改指定索引下标的元素: lset key index newValue

5、阻塞操作

·阻塞式弹出如下:blpop key [key ...] timeout和brpop key [key ...] timeout

(blpop和brpop是lpop和rpop的阻塞版本,它们除了弹出方向不同,使用方法基本相同,所以下面以brpop命令进行说明,

brpop命令包含两个参数:·key[key...]:多个列表的键。

·timeout:阻塞时间(单位:秒)。

1)列表为空:如果timeout=3,那么客户端要等到3秒后返回,如果timeout=0,那么客户端一直阻塞等下去

如果此期间添加了数据element1,客户端立即返回

2)列表不为空:客户端会立即返回。

在使用brpop时,有两点需要注意

第一点,如果是多个键,那么brpop会从左至右遍历键,一旦有一个键能弹出元素,客户端立即返回:

第二点,如果多个客户端对同一个键执行brpop,那么最先执行brpop命令的客户端可以获取到弹出的值

3、内部编码

列表类型的内部编码有两种。

·ziplist(压缩列表):当列表的元素个数小于list-max-ziplist-entries配置(默认512个),同时列表中每个元素的值都小于list-max-ziplist-value配置时(默认64字节),Redis会选用ziplist来作为列表的内部实现来减少内存的使用。

·linkedlist(链表):当列表类型无法满足ziplist的条件时,Redis会使用linkedlist作为列表的内部实现。

4、使用场景

1、消息队列:

Redis的lpush+brpop命令组合即可实现阻塞队列,生产者客户端使用lrpush从列表左侧插入元素,多个消费者客户端使用brpop命令

阻塞式的“抢”列表尾部的元素,多个客户端保证了消费的负载均衡和高可用性。

2、文章列表

每个用户有属于自己的文章列表,现需要分页展示文章列表。此时可以考虑使用列表,因为列表不但是有序的,同时支持按照索引范围获取元素。

实际上列表的使用场景很多,在选择时可以参考以下口诀:

·lpush+lpop=Stack(栈)

·lpush+rpop=Queue(队列)

·lpsh+ltrim=Capped Collection(有限集合)

·lpush+brpop=Message Queue(消息队列)

参考资料:《Redis开发与运维》

原文地址:https://www.cnblogs.com/jnba/p/10811906.html

时间: 2024-10-08 21:45:18

Redis学习——数据结构上的相关文章

Redis学习——数据结构介绍(四)

一.简介 作为一款key-value 的NoSQL数据库,Redis支持的数据结构比较丰富,有:String(字符串) .List(列表) .Set(集合) .Hash(哈希) .Zset(有序集合),相对于其他四种数据结构,Zset 是Redis独有的数据结构,作为有序的集合来使用还是十分方便的,下面我来介绍这集中数据结构: 数据类型 描述 set 无序.不重复的字符串集合 list 字符串链表 string 字符串.整型.浮点型 hash key和value都是无序的hashtable zs

Redis学习——数据结构下

4.集合(集合(set)类型也是用来保存多个的字符串元素,但和列表类型不一样的是,集合中不允许有重复元素,并且集合中的元素是无序的,不能通过索引下标获取元素.) 1.命令 .集合内操作 1.添加元素 sadd key element [element ...]返回结果为添加成功的元素个数. 2.删除元素 srem key element [element ...]返回结果为成功删除元素个数. 3.计算元素个数 scard key (scard的时间复杂度为O(1),它不会遍历集合所有元素,而是直

Redis学习 数据结构

本文参考了Redis源码3.0分支和<Redis设计与实现>. 对象 Redis基于下面提到的底层数据结构创建了一个对象系统,这个系统包括String.List.Set.Hash.Sorted Set这五种对象,每种对象都用到了至少一种底层数据结构.Redis中的每个对象都由一个redisObject结构表示,该结构中和保存数据有关的三个属性分别是type.encoding和ptr. /* Object types */ #define REDIS_STRING 0 #define REDIS

分布式缓存技术redis学习系列(一)——redis简介以及linux上的安装

redis简介 redis是NoSQL(No Only SQL,非关系型数据库)的一种,NoSQL是以Key-Value的形式存储数据.当前主流的分布式缓存技术有redis,memcached,ssdb,mongodb等.既可以把redis理解为理解为缓存技术,因为它的数据都是缓存在内从中的:也可以理解为数据库,因为redis可以周期性的将数据写入磁盘或者把操作追加到记录文件中.而我个人更倾向理解为缓存技术,因为当今互联网应用业务复杂.高并发.大数据的特性,正是各种缓存技术引入最终目的. 关于r

分布式缓存技术redis学习(一)——redis简介以及linux上的安装

redis简介 redis是NoSQL(No Only SQL,非关系型数据库)的一种,NoSQL是以Key-Value的形式存储数据.当前主流的分布式缓存技术有redis,memcached,ssdb,mongodb等.既可以把redis理解为理解为缓存技术,因为它的数据都是缓存在内从中的:也可以理解为数据库,因为redis可以周期性的将数据写入磁盘或者把操作追加到记录文件中.而我个人更倾向理解为缓存技术,因为当今互联网应用业务复杂.高并发.大数据的特性,正是各种缓存技术引入最终目的. 关于r

redis学习(二) redis数据结构介绍以及常用命令

redis数据结构介绍 我们已经知道redis是一个基于key-value数据存储的数据结构数据库,这里的key指的是string类型,而对应的value则可以是多样的数据结构.其中包括下面五种类型: 1.string 字符串 string字符串类型是redis最基础的数据存储类型.string是最基础的一种数据类型,其可以拓展为某种特定类型,例如普通文本,json字符串,二进制数据等等.就本质上来说,接下来要介绍的hash,list,set等其内部最基础的组成单位依然是string,只不过re

Redis各种数据结构性能数据对比和性能优化实践

很对不起大家,又是一篇乱序的文章,但是满满的干货,来源于实践,相信大家会有所收获.里面穿插一些感悟和生活故事,可以忽略不看.不过听大家普遍的反馈说这是其中最喜欢看的部分,好吧,就当学习之后轻松一下. Redis各种数据结构性能数据对比 测试工具:perf4j 性能指标:平均值,最小值,最大值,方差 对比将814条数据按单条插入到哈希MAP和哈希SET: 对比从814条数据的哈希MAP和哈希SET中判断一个元素是否存在(map的hasKey和set的isMember): 大量数据插入哈希MAP,运

分布式缓存技术redis学习系列(四)——redis高级应用(集群搭建、集群分区原理、集群操作)

本文是redis学习系列的第四篇,前面我们学习了redis的数据结构和一些高级特性,点击下面链接可回看 <详细讲解redis数据结构(内存模型)以及常用命令> <redis高级应用(主从.事务与锁.持久化)> 本文我们继续学习redis的高级特性--集群.本文主要内容包括集群搭建.集群分区原理和集群操作的学习. Redis集群简介 Redis 集群是3.0之后才引入的,在3.0之前,使用哨兵(sentinel)机制(本文将不做介绍,大家可另行查阅)来监控各个节点之间的状态.Redi

大数据高性能数据库Redis在Windows上的配置

Redis学习笔记----Redis在windows上的安装和配置 Redis简介 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set --有序集合)和hash(哈希类型).这些数据类型都支持push/pop.add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的.在此基础上,redis支持各种不同方式的排序.与memcach