`

Redis-3 数据类型详解之List

阅读更多

1. 理论篇

在学习List之前先对其来一点理论的了解是有好处的。

简单来说比如 10,20,1,2,3  的序列就是一个List。不过 List 是继承自ArrayList 还是LinkedList,他们之间的差别还是很大的。LinkedList 意味着即使你的 List 列表中有一百万个数据,在 List 的头或者 尾部插入数据的时间都是恒定的。比如无论数组里面有10个或者1000万个元素,使用LPUSH 把一个元素插入到 List 的头部或者尾部的时候,他们的时间是相等的。

 

那他的确定是什么呢?在使用下表访问 ArrayList 的元素的时候,它的速度很快,可以说是及时的;而在访问 LinkedList 的元素的额时候,速度就不那么快了,它与访问的元素的下标的数量是有关的。

 

Redis List 是继承自LinkedList 的,因为对于数据库来说能够在长列表的时候非常快的插入数据是非常关键的。另一个重要的因素是你即将要看到的:Redis 可以在常数时间内取得常数长度。

 

当访问一个大集合的中部元素是比较重要的时候,还有其他的数据结构可以使用--Sorted Set。我们后续的教程会讲 Sorted Set。

2. Redis List 入门

LPUSH 命令添加一个新元素到一个列表的左边(头部),然而RPUSH 命令添加一个新元素到一个列表的右边(尾部)。最后,LRANGE命令在列表中获取一个范围的元素。

 

Java代码 
  1. 127.0.0.1:6666> RPUSH mylist a  
  2. (integer) 1  
  3. 127.0.0.1:6666> rpush mylist b  
  4. (integer) 2  
  5. 127.0.0.1:6666> lpush mylist first  
  6. (integer) 3  
  7. 127.0.0.1:6666> lrange mylist 0 -1  
  8. 1"first"  
  9. 2"a"  
  10. 3"b"  

 注意LRANGE 有两个下表,范围内的第一个和最后一个元素都会返回。两个下标都可以是负值,这告诉 Redis 从末尾开始计数:所以 -1 是最后一个元素,-2 是倒数第二个元素等等。

 

正如你所见,RPUSH 添加元素到列表的右边,而LPUSH 添加元素到列表的左边。

这两个命令都是可变参数的命令,这意味着你可以很随意的添加多个元素到列表中。

 

Java代码 
  1. 127.0.0.1:6666> rpush mylist 1 2 3 4 5 "mylast"  
  2. (integer) 9  
  3. 127.0.0.1:6666> lrange mylist 0 -1  
  4. 1"first"  
  5. 2"a"  
  6. 3"b"  
  7. 4"1"  
  8. 5"2"  
  9. 6"3"  
  10. 7"4"  
  11. 8"5"  
  12. 9"mylast"  

 

Redis 列表上定义的一个重要的操作是弹出元素(pop elements)。弹出元素操作即使Redis 列表检索元素的操作,同时也是列表消除元素的操作。你可以从左边和右边弹出元素,与你从左边和右边添加元素是非常相似的:

Java代码 
  1. 127.0.0.1:6666> rpush mylist a b c  
  2. (integer) 3  
  3. 127.0.0.1:6666> rpop mylist  
  4. "c"  
  5. 127.0.0.1:6666> lpop mylist  
  6. "a"  
  7. 127.0.0.1:6666> lpop mylist  
  8. "b"  

 

我们往列表中添加了三个元素,也弹出了三个元素,那么列表现在则是空的。如果我们尝试再继续弹出元素,那么将获得如下结果:

Java代码 
  1. 127.0.0.1:6666> lpop mylist  
  2. (nil)  

 

如果列表中没有元素,Redis 则会返回一个 NULL 值。

 

 3. 列表的常见使用情形

列表对于多任务是非常又有用的,下面是两个非常有代表性的用法:

  • 记录用户提交到社交网络上的最新的更新
  • 进程间的通信,使用生产者-消费者模式,生产者把一个条目压进列表中,消费者消费这些条目并且执行动作。Redis 有特别的列表命令可以使这种情况更加可靠和高效。

 

 注:此部分官方文档有实例,可以看看

 

 4.有上限的列表

在很多场景中,我们仅仅使用List存储最新的条目,无论他们是下面的:社交网络更新、日志或者其他什么。

 

Redis 列表允许我们使用列表作为一个有上限的集合,它使用LTRIM仅存储最新的条目并且丢弃最旧的数据。

LTRIM 命令与LRANGE命令十分相似,它不展示指定的元素范围而是把这个范围设置为新的列表值。给定的范围之外的元素会被移除。

Java代码 
  1. 127.0.0.1:6666> rpush mylist 1 2 3 4 5  
  2. (integer) 5  
  3. 127.0.0.1:6666> ltrim mylist 0 2  
  4. OK  
  5. 127.0.0.1:6666> lrange mylist 0 -1  
  6. 1"1"  
  7. 2"2"  
  8. 3"3"  

 

下面的 LTRIM 命令告诉Redis仅仅保留从下标0到2的元素,其他的都被丢弃。这就允许一个非常简单的但是有用的模式:对一个列表进行压入操作 +列表调整操作组合,这为了实现添加一个新的元素并且丢弃掉超出限制的元素:

Java代码 
  1. LPUSH mylist <some element>  
  2. LTRIM mylist 0 999  

 

 上面的组合添加一个新的元素,并且仅仅把最新的1000个元素保存入列表中。使用LRANGE你可以访问最顶部的元素而且不需要记住特定的老数据。

注:虽然LRANGE从技术上讲是个O(N) 命令,但是访问列表头部或者尾部的小范围是个及时的操作。

 

5. 列表的阻塞操作

 列表有一个特别的特性使其适合实现队列,并且通常作为一个内部进程通信系统的构建基块:阻塞操作。

 

比如你想要使用一个进程把条目压入列表,并且使用一个不同的进程来实际上对这些条目做一些工作。这是普通的生产者/消费者模式,并且可以使用下面的方式来实现:

  • 要把条目压入列表,生产者调用LPUSH
  • 要从列表中提取或者处理条目,消费者调用RPOP

然而,很有可能有时列表是空的并且没有什么可处理的,所以RPOP仅仅返回NULL。在这种情况下,消费者别强制等待一些时间并且使用RPOP重试。这被称作轮询(polling),并且在这种情形下他不是一个好的做法,因为它有如下缺点:

  1. 强制Redis和客户端运行无用的命令(当列表为空的时候,所有的请求都在做无用功,他们仅仅返回NULL)
  2. 在消费者NULL的时候,为条目的处理添加一个延迟,它等待一段时间。为了使延迟更小,we could wait less between calls to RPOP, with the effect of amplifying problem number 1, i.e. more useless calls to Redis.

所以,Redis实现了BRPOP 和 BLPOP 命令,他们是当列表为空时可以阻塞版本的 RPOP 和 LPOP :他们仅仅当一个新的元素被添加进入列表的时候或者当用户指定的过期时间到达的时候才返回给调用者。

 

下面是我们可以在工作者中(worker)调用BRPOP的例子:

 

Java代码 
  1. 127.0.0.1:6666> brpop tasks 10  
  2. 1"tasks"  
  3. 2"12"  

 

 

这个效果是我在执行完上述的命令之后,程序阻塞了;然后在另一个客户端执行了 RPUSH tasks 12 命令,这时候阻塞的程序就会继续执行,因为它检测到了有新的元素的进入。

 

 brpop tasks 10 的含义是:等待 tasks 列表中的元素,但是如果在 5 秒以后还没有元素可以获取到的话就返回程序。

 

注意:你可以使用 0 作为过期时间以一直等待元素,并且你也可以指定多个而不止一个列表,这样可以同时等待多个列表,并且当第一个列表收到元素时收到通知。

 

关于BRPOP的几个值得注意的地方:

1. 客户端以一种有序的方式接受服务:当一个元素被其他客户端压入到列表中或者其他情况,一个列表阻塞等待的第一个客户端将会接收到服务。

2. 返回值与RPOP相比是不一样的:由于它也包含着键的名字,所以它是两个元素的数组,这是因为BRPOP 和 BLPOP 能够等待来自多个列表的元素。

3. 如果已经到了过期时间,那么将返回NULL。

 

关于列表和他的阻塞选项,你还有很多需要了解的。关于下述的内容建议你读更多资料:

  • 可以使用RPOPLPUSH来构建安全的队列或者循环队列
  • BRPOPLPUSH 是命令的命令的阻塞备选方案

额。。。下面依然是我建的一个公众帐号,可以关注一下哦,谢谢

 

1
2
分享到:
评论

相关推荐

    Redis进阶实践之十四 Redis-cli命令行工具使用详解第一部分.md

    ### Redis进阶实践之十四:Redis-cli命令行工具使用详解(第一部分) #### 工具概述 ##### Redis-cli 简介 Redis-cli 是 Redis 官方提供的一个强大的命令行客户端工具,它允许用户直接与 Redis 服务器进行交互,...

    redis-mongodb-zookeeper-memcache安装

    - **数据类型的选择:** 根据不同的应用场景选择合适的数据类型。例如,对于计数器类的功能,可以选择使用 `string` 类型;对于列表操作,可以选择 `list` 类型等。 通过上述步骤,可以成功地安装并使用 Redis。...

    Another-Redis-Desktop-Manager.1.4.2.zip

    软件提供键值对的浏览界面,支持各种数据类型如字符串(String)、哈希(Hash)、列表(List)、集合(Set)和有序集合(Sorted Set)。用户可以直接在界面上查看和编辑键值,支持JSON格式的数据展示。 4. **命令...

    redis-win-2.8.2101

    7. 数据类型操作:Redis支持五大数据类型:String(字符串)、Hash(哈希)、List(列表)、Set(集合)、Sorted Set(有序集合)。每种类型都有其独特用途,例如,String适合存储简单数据,List可以实现消息队列...

    redis-2.8.9

    Redis 支持五种基本数据类型:字符串(String)、哈希(Hash)、列表(List)、集合(Set)和有序集合(Sorted Set)。这些类型提供了丰富的操作命令,如设置、获取、删除、更新、追加、排序等,满足不同场景的需求...

    redis-desktop-manager

    5. **数据类型支持**:全面支持Redis的数据类型,如字符串(String)、哈希表(Hash)、列表(List)、集合(Set)和有序集合(Sorted Set)。 6. **事务处理**:可以执行Redis的事务(Transaction),确保数据操作...

    redis-使用安装

    1. **字符串(String)**:最基础的数据类型,可以存储任何字符串,也可以用于计数或存储简单的 JSON 对象。 2. **哈希(Hash)**:存储键值对的集合,适合存储对象。 3. **列表(List)**:按插入顺序存储元素,可...

    redis-缓存文档

    ### Redis缓存技术详解 #### 一、Redis简介与缓存概念 ...通过以上介绍,我们了解到Redis不仅是一种高性能的缓存系统,还具有丰富的数据类型和强大的持久化能力,是现代软件开发中不可或缺的工具之一。

    Redis-x64-3.2.100.rar

    4. **数据类型**:Redis支持五种基本数据类型:String、List、Set、Hash和Sorted Set,它们提供了丰富的操作命令。 5. **持久化机制**:Redis有两种持久化方式,RDB(定期保存整个数据库状态)和AOF(记录所有写...

    redis-cheatsheet-v1

    Redis是一款开源的、高性能的键值存储系统,因其在数据处理速度上的卓越表现而备受青睐。本文将深入解析Redis命令行工具的使用方法,包括启动服务器、运行客户端以及各种核心命令的应用场景,帮助您快速掌握Redis的...

    Redis+redis-desktop-manager

    Redis支持五种基本数据类型:字符串(String)、哈希(Hash)、列表(List)、集合(Set)和有序集合(Sorted Set),这些数据类型可以满足多种应用场景。 **Redis的主要特点** 1. **内存存储**:Redis将所有数据...

    Redis-x643_2_100.msi

    1. **数据结构与数据类型:** Redis 支持多种数据结构,如字符串(String)、哈希(Hash)、列表(List)、集合(Set)和有序集合(Sorted Set)。这些数据结构为应用程序提供了丰富的操作,比如存储用户信息、缓存...

    redis64 for windows

    - 数据类型:Redis支持字符串(String)、哈希(Hash)、列表(List)、集合(Set)和有序集合(Sorted Set)等五种基本数据类型,满足不同应用场景的需求。 - 持久化:Redis提供了RDB和AOF两种持久化方式,确保在系统崩溃后...

    redis-笔记

    本笔记将深入探讨Redis的各种数据类型及其操作命令,持久化机制,以及集群配置。 1. 数据类型与操作命令: - 字符串(String):支持设置、获取、增加、减少等操作,如`SET key value`、`GET key`、`INCR key`。 - ...

    Redis支持的数据类型、相关命令和功能

    ### Redis支持的数据类型及相关命令详解 #### 一、Redis简介及数据类型概述 Redis是一种开源的、基于内存的键值存储系统,同时也被广泛视为一种数据结构服务器。它支持多种数据类型,包括字符串(Strings)、列表...

    redis 数据类型详解 以及 redis适用场景场合

    ### Redis 数据类型详解 Redis是一种高性能的键值存储系统,提供了多种数据结构的支持,使得它在不同的应用场景下都能够表现出色。接下来,我们将详细介绍Redis中的主要数据类型及其应用场景。 #### String 字符串...

    phpredis扩展

    2. **全面支持Redis命令**:phpredis覆盖了Redis的所有主要命令,包括字符串、哈希、列表、集合、有序集合等数据类型的操作。 3. **连接池**:支持连接池管理,减少建立和关闭连接的开销,提高系统响应速度。 4. **...

    04次课 redis-02 常用命令.doc

    Redis 支持五种基本数据类型,即 String、Hash、List、Set 和 Sorted Set。每种数据类型都有其特点和应用场景。 * String(字符串):最基本的数据类型,二进制安全,可以包含任何数据,例如图片、视频等。 * Hash...

    redis安装以及测试文档

    ### Redis 安装与测试详解 #### 一、Server端安装流程 ##### 1. 下载Redis - **源码地址**: [https://github.com/MSOpenTech/redis](https://github.com/MSOpenTech/redis) - **推荐版本**: redis2.6 - **下载...

    php 操作 redis

    String 类型是 Redis 最基本也是最常用的数据类型之一,它可以用来存储任何格式的数据,包括文本、图片等二进制数据。 - **设置和获取键值** - `$redis-&gt;set('key','TK');`:设置键 `key` 的值为 `TK`。 - `$...

Global site tag (gtag.js) - Google Analytics