try redis (三) - 数据类型和抽象

来源:互联网 发布:lol什么意思网络用语 编辑:程序博客网 时间:2024/06/05 09:04

官方文档地址 - http://www.redis.io/topics/data-types-intro

参考地址:http://bbs.itcast.cn/thread-17267-1-1.html

redis 不仅仅是简单的 key-value 存储。实际上可以理解为它是一个数据结构服务。在传统的key-value 存储中,我们一般是 把 string(key)<->string(value)关联起来的。在redis中。value不仅仅是一个简单的string类型,也可以是一个复杂的数据结构。下面将列出所有redis支持的数据结构。

  • Binary-safe strings.
  • Lists: collections of string elements sorted according to the order of insertion. They are basically linked lists.
  • Sets: collections of unique, unsorted string elements.
  • Sorted sets, similar to Sets but where every string element is associated to a floating number value, called score. The elements are always taken sorted by their score, so unlike Sets it is possible to retrieve a range of elements (for example you may ask: give me the top 10, or the bottom 10).
  • Hashes, which are maps composed of fields associated with values. Both the field and the value are strings. This is very similar to Ruby or Python hashes.
  • Bit arrays (or simply bitmaps): it is possible, using special commands, to handle String values like an array of bits: you can set and clear individual bits, count all the bits set to 1, find the first set or unset bit, and so forth.
  • HyperLogLogs: this is a probabilistic data structure which is used in order to estimate the cardinality of a set. Don't be scared, it is simpler than it seems... See later in the HyperLogLog section of this tutorial.


Redis keys 

Redis Keys 是一个二进制安全的。这也就意味着我们可以使用任何二进制序列来作为key,从string 类型到 一张 jpg 图片的内容,都可以作为key.空字符串("")也是有效的key.

几点关于keys 的原则

 1、使用太长的keys 不是一个好的方式。除了使用除了内存的浪费,还有在数据集中搜索这个key是需要一些很代价很高的key比较。

2、使用太短的keys 一般也不是好的方式。例如相比key 为“u1000flw",我们可以写成"user:1000:followerr".后者的可读性更好,而多使用的空间且相对于对象本身或者value object 是可以忽略不计的。当然更短的keys 明显是会消耗更少的空间。这个在实际项目中再做平衡。

3、尝试使用一种风格。例如,"object-type:id" 和"user:100" 都是比较好的方式。小数点(.)和破折号(-) 多用于多单词的字段中。

4、keys的最大允许值是 512MB


Redis Strings 

String 是我们可以接触到的最简单的。用的也比较多。不多说了。

具体的命令使用,可以看 http://blog.csdn.net/wei_ya_wen/article/details/39962841 中的 前三节

要注意的是 值不能够大于 512MB


Redis Lists

LIST 在广义上的定义为一个顺序排列的的元素集合。但是List中 Array(顺序表) 和Linked(链表)的方式是很不一样的。

redis 的lists 是通过Linked Lists 实现的。因为对于一个数据集系统来说,想在一个很长的List中添加 元素应该是要非常快的。

List 中常用命令 RPUSH, LPUSH, LLEN, LRANGE, LPOP, and RPOP 请看 http://blog.csdn.net/wei_ya_wen/article/details/39962841 中的 第四节

list常见的两种用例

1、选择性的控制哪些元素需要储存。哪些元素需要去除。

2、处理系统之间的交互。使用一个生产者-消费者模式。生产者放元素在list中,消费者消费这些元素,并且执行一些动作。redis 有一些特殊的LIST命令能够使得这些使用场景更稳定和高效


Lists 中的阻塞操作

Lists 可以很简单的用来实现一个队列(Queue),在构建块的通信系统中,我们常常用到阻塞操作


针对生产者,消费者中 。一个线程往 List中放element,一个消费线程从List中取东西,可以用一个简单的方式来处理

1、生产者线程调用 LPUSH 从左往右放element

2、消费者线程调用RPOP 从右往左出队列

然而,有时候当List为空。没有元素可以拿出来处理的时候,RPOP会拿到Null值。对于这种情况,消费者只有wait一段时间,然后尝试重新RPOP.这种方式有几个缺点:

缺点1:强迫redis和客户端做一些无用的操作(尤其是List为空的时候)

缺点2:客户端需要添加延迟,对于系统的效率是有影响的。类似轮训的处理肯定对消费者的时效性肯定也有影响


所以redis 实现的利益个命令 叫做 BRPOP 和BLPOP .与RPOP 和 LPOP 的唯一区别就是当List为空的时候,阻塞当前线程。

举个例子

> brpop tasks 51) "tasks"2) "do_something"
这个意味着,如果List为空,阻塞当前线程,直到List有数据或者阻塞时间超过5秒

特别注意的是,0默认永远不超时。


Redis Hashes:

redis 对hash 的一些命令,具体可看:    http://blog.csdn.net/wei_ya_wen/article/details/40898787  第二节.

hashes 一般可以当方便的当做对象来处理。对于filed的数量,没有限制。


Redis Sets

Redis Sets  是无序的 strings 集合。 具体命令 可以看  http://blog.csdn.net/wei_ya_wen/article/details/39962841 第五节


Bitmaps:

Bitmaps 其实不是一种数据类型。是一组针对String类型的面向bit操作。因为string类型是二进制数据类型。最大长度只有512M,相当于2^32个bit位。

特别说说 SETBIT命令。

SETBIT(key offset value)
说明:该操作的时间复杂度为O(1)。设置或者清除存储在key上的字符串在指定偏移处的位值。命令中的value可以指定为0或者1,根据value的不同,位值可以被设置或者被清除。当该key不存在时,将会创建一个新的字符串的值。字符串的长度可以增长以便能够包含offset偏移处的值。命令中的offset的值需要大于或者等于0,但是需要小于2^32。这会将位图(bitmaps)的大小限定在512MB以内。当存储在该key上的字符串被扩展时,增加的位将会被设置为0。需要注意的是,当设置最后一个可能的位(偏移值等于232-1)并且存储在该key上的字符串值还并没包含字符串值或者包含长度较小的字符串值时,Redis需要重新分配中间内存,这可能会阻塞服务器一段时间。一旦第一次分配空间分配完成后,对相同keys后续的SETBIT调用将不再有空间分配的开销。
返回值:返回在offset偏移处的原有的位值。

引用一个简单的例子:日活跃用户
    为了统计今日登录的用户数,我们建立了一个bitmap,每一位标识一个用户ID。当某个用户访问我们的网页或执行了某个操作,就在bitmap中把标识此用户的位置为1。在Redis中获取此bitmap的key值是通过用户执行操作的类型和时间戳获得的。

       这个简单的例子中,每次用户登录时会执行一次redis.setbit(daily_active_users, user_id, 1)。将bitmap中对应位置的位置为1,时间复杂度是O(1)。统计bitmap结果显示有今天有9个用户登录。Bitmap的key是daily_active_users,它的值是1011110100100101。

    因为日活跃用户每天都变化,所以需要每天创建一个新的bitmap。我们简单地把日期添加到key后面,实现了这个功能。例如,要统计某一天有多少个用户至少听了一个音乐app中的一首歌曲,可以把这个bitmap的redis key设计为play:yyyy-mm-dd-hh。当用户听了一首歌曲,我们只是简单地在bitmap中把标识这个用户的位置为1,时间复杂度是O(1)。

官网上提供的一个例子是:

For example imagine you want to know the longest streak of daily visits of your web site users. You start counting days starting from zero, that is the day you made your web site public, and set a bit with SETBIT every time the user visits the web site. As a bit index you simply take the current unix time, subtract the initial offset, and divide by 3600*24.

This way for each user you have a small string containing the visit information for each day. With BITCOUNT it is possible to easily get the number of days a given user visited the web site, while with a few BITPOS calls, or simply fetching and analyzing the bitmap client-side, it is possible to easily compute the longest streak.

说白了,就是想知道知道每个用户的在网站上登陆的一个详细的记录。用来做统计使用。

setbit(key,offset,value)

key: 当然是userId,

offset: (当前时间 - 初始值)/3600*24          --这个初始值可以设置为开始统计的哪一天。避免因为当前时间过大,从而造成offset的值过大。浪费空间

value: 0/1

比如想知道 userId 为 user1 的用户一共在系统登录过多少次 。 只需要 调用 BITCONT user1 就可以了。非常简单的就能统计出来了.








0 0
原创粉丝点击