【Redis】List 列表

文章目錄

  • 初識列表
  • 常用命令
    • lpush
    • lpushx
    • lrange
    • rpush
    • rpushx
    • lpop & rpop
    • lindex
    • linsert
    • llen
    • 阻塞操作 —— blpop & brpop
  • 內部編碼
  • 應用場景

在這里插入圖片描述

初識列表

列表類型,用于存儲多個字符串。在操作和實現上,類似 C++ 的雙端隊列,支持隨機訪問(O(N)),頭插頭刪尾插尾刪(O(1)),詳細可參看【C++】deque 雙端隊列

大致實現為,使用一個數組,其中每個元素都是一個數組指針。從數組中間開始插入元素,頭插則從中間往前插入,尾插則從中間往后插入在這里插入圖片描述

Redis 實現的列表如下圖,有相對順序,規定左邊為頭,下標從0開始,如下圖。每個元素從左到右構成一個有序的列表,此處的有序是有順序,不是排序。列表的每個字符串稱為元素,允許有重復的值,一個列表最多存儲 232 - 1 個元素。
功能上,支持從兩端插入(push)和彈出(pop),還可以獲取指定范圍的元素列表,獲取指定索引下標的元素,常被用于實現隊列

在這里插入圖片描述

在這里插入圖片描述

常用命令

lpush

將一個或多個元素從左側插入(頭插)到 list 中。left push

lpush key element [element …]

返回值:完成插入操作后,list 的長度
示例:

127.0.0.1:6379> lpush list1 1 2 3 4
(integer) 4

lpushx

在 key 存在時才能將一個或多個元素從左側插入(頭插)到 list 中,不存在 key 則直接返回。left push exist

lpushx key element [element …]

返回值:完成插入操作后,list 的長度
示例:

127.0.0.1:6379> lpushx list1 6 7 8 9
(integer) 8
127.0.0.1:6379> lpushx list2 1234
(integer) 0

lrange

獲取指定范圍的 list 的元素,從 start 到 stop,左閉右閉
其中 start 和 stop 的值可正可負,負數則表示倒數,-1 表示倒數第一個數,-2 代表倒數第二個數,以此類推

PS:lrange 是 list range,而不是 left range,而是 ,所以沒有 rrange

lrange key start stop

返回值:指定區間的元素
備注:如果指定的區間不存在或無值,則返回空。若指定的區間有部分越界,并不會報錯,而是把能返回的值返回
示例:

127.0.0.1:6379> lrange list2 0 -1
(empty array)
127.0.0.1:6379> lrange list1 0 -1
1) "9"
2) "8"
3) "7"
4) "6"
5) "4"
6) "3"
7) "2"
8) "1"
127.0.0.1:6379> lrange list1 100 300
(empty array)
127.0.0.1:6379> lrange list1 0 300
1) "9"
2) "8"
3) "7"
4) "6"
5) "4"
6) "3"
7) "2"
8) "1"

因為插入元素時使用的是 lpush 和 lpushx,會將元素從左往右依次插入

在這里插入圖片描述

rpush

將一個或者多個元素從右側插入(尾插),right push

rpushx key element [element …]

返回值:插入后 list 的長度
示例:

127.0.0.1:6379> rpush key2 1 2 3 4
(integer) 4
127.0.0.1:6379> lrange key2 0 -1
1) "1"
2) "2"
3) "3"
4) "4"

rpushx

在 key 存在時才能將一個或多個元素從右側插入(尾插)到 list 中,不存在 key 則直接返回。reft push exist

rpushx key element [element …]

返回值:完成插入操作后,list 的長度
示例:

127.0.0.1:6379> rpush key2 6 7 8 9
(integer) 8
127.0.0.1:6379> lrange key2 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
5) "6"
6) "7"
7) "8"
8) "9"

lpop & rpop

lpop

從 list 的左側取出元素(頭刪),left pop

lpop key

返回值:取出的元素或者 nil
示例:

127.0.0.1:6379> lrange list1 0 -1
1) "9"
2) "8"
3) "7"
4) "6"
5) "4"
6) "3"
7) "2"
8) "1"
127.0.0.1:6379> lpop list1
"9"
127.0.0.1:6379> lpop list1
"8"
127.0.0.1:6379> lpop list1
"7"
127.0.0.1:6379> lpop list1
"6"
127.0.0.1:6379> lrange list1 0 -1
1) "4"
2) "3"
3) "2"
4) "1"

rpop

從 list 右側取出元素(尾刪),right pop

rpop key

返回值:取出的元素或 nil
示例:

127.0.0.1:6379> lrange list1 0 -1
1) "4"
2) "3"
3) "2"
4) "1"
127.0.0.1:6379> rpop list1
"1"
127.0.0.1:6379> rpop list1
"2"
127.0.0.1:6379> rpop list1
"3"
127.0.0.1:6379> rpop list1
"4"
127.0.0.1:6379> rpop list1
(nil)
127.0.0.1:6379> lrange list1 0 -1
(empty array)

lindex

獲取從左往右數下標為 index 的元素,list index
index 支持正數或負數,負數則表示倒數第 index 個

lindex key index

返回值:取出的元素或者 nil
示例:

127.0.0.1:6379> lrange key2 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
5) "6"
6) "7"
7) "8"
8) "9"
127.0.0.1:6379> lindex key2 0
"1"
127.0.0.1:6379> lindex key2 1
"2"
127.0.0.1:6379> lindex key2 -1
"9"
127.0.0.1:6379> lindex key2 -2
"8"

linsert

在特定位置插入元素,list insert

linsert key <before | after> pivot element

返回值:插入后 list 的長度
備注:pivot 是列表中存在的數,可選擇在其前插入或其后插入,若列表不存在該數,則返回 -1。如果列表存在多個 pivot,因為是從左往右遍歷,只會找到第一個
示例:

127.0.0.1:6379> lrange key1 0 -1
1) "7"
2) "6"
3) "5"
4) "3"
5) "4"
6) "3"
7) "2"
8) "1"
127.0.0.1:6379> linsert key1 before 3 100
(integer) 9
127.0.0.1:6379> lrange key1 0 -1
1) "7"
2) "6"
3) "5"
4) "100"
5) "3"
6) "4"
7) "3"
8) "2"
9) "1"
127.0.0.1:6379> linsert key1 after 3 200
(integer) 10
127.0.0.1:6379> lrange key1 0 -11) "7"2) "6"3) "5"4) "100"5) "3"6) "200"7) "4"8) "3"9) "2"
10) "1"
127.0.0.1:6379> linsert key1 after 10 200
(integer) -1

llen

獲取 list 的長度,list len

llen key

返回值:list 的長度
示例:

127.0.0.1:6379> lrange key1 0 -11) "7"2) "6"3) "5"4) "100"5) "3"6) "200"7) "4"8) "3"9) "2"
10) "1"
127.0.0.1:6379> llen key1
(integer) 10

阻塞操作 —— blpop & brpop

blpopbrpop 是 lpop 和 rpop 的阻塞版本,block left pop 和 block right pop

blpop key [key …] timeout
brpop key [key …] timeout

作用基本一致,但有以下區別:

  1. 在列表有元素的情況下,阻塞版本和非阻塞的表現是一致的,都直接取出元素并返回。但如果列表沒有元素,非阻塞版本會直接返回 nil,而阻塞版本會根據 timeout,阻塞一段時間,期間 Redis 服務端可以執行其他命令,但執行該命令的客戶端會進行阻塞狀態
  2. blpop 和 brpop 可以支持取出多個列表的元素,如果設置了多個列表,那么會從左往右依次嘗試進行取出操作,一旦有一個列表不為空,可以彈出元素,則進行彈出操作并返回元素。即并不是彈出多個列表的元素,而是從這些列表中彈出一個元素
  3. 如果多個客戶端同時對同一個列表進行阻塞彈出操作,則最先執行命令的客戶端會先嘗試進行彈出操作,如果列表為空,則都阻塞,直到列表有元素,也是最先執行命令的客戶端可以彈出元素
  4. timeout 單位為秒

示例:

127.0.0.1:6379> keys *
1) "key2"
2) "key1"
127.0.0.1:6379> lrange key1 0 -1
1) "4"
2) "3"
3) "2"
4) "1"
127.0.0.1:6379> lrange key2 0 -1
1) "1"
2) "1"
3) "11"
127.0.0.1:6379> blpop key1 key2 10
1) "key1"
2) "4"
127.0.0.1:6379> blpop key3 key2 10
1) "key2"
2) "1"

內部編碼

在舊版本時,列表的內部編碼有兩種:

  • ziplist(壓縮列表):當列表的元素個數小于 list-max-ziplist-entries 配置(默認 512 個),同時列表中每個元素的長度都小于 list-max-ziplist-value 配置(默認 64 字節)時,Redis 會選用 ziplist 來作為列表的內部編碼實現來減少內存消耗。
  • linkedlist(鏈表):當列表類型無法滿足 ziplist 的條件時,Redis 會使用 linkedlist 作為列表的內部實現。

在較新版本,列表的內部編碼統一使用 quicklist 實現

127.0.0.1:6379> object encoding key1
"quicklist"

應用場景

模擬棧或隊列

列表使用雙端隊列,兩端的插入和刪除很高效,而棧和隊列都是操作受限的隊列,雙端隊列非常適合實現,C++ 的 STL 也是如此,queue 和 stack 的底層都使用 deque(雙端隊列)實現

  • 當只使用同一端操作時,即 lpush & lpoprpush & rpop 即可模擬棧
  • 當只使用對端相反操作時,即 lpush & rpoprpush & lpop 即可模擬隊列

消息隊列

如下圖所示

在這里插入圖片描述

Redis 可使用 lpush + brpop 命令組合實現經典的阻塞式生產者 - 消費者模型隊列,生產者客戶端使用 lpush 從列表左側插入元素,多個消費者客戶端使用 brpop 命令,阻塞式地從隊列中取出元素。通過多個客戶端來保證消費的負載均衡和高可用性


分頻道的消息隊列

如圖下圖所示

在這里插入圖片描述

Redis 同樣使用 lpush + brpop 命令,但通過不同的鍵模擬頻道的概念,不同的消費者可以通過 brpop 獲取不同的鍵值,實現訂閱不同頻道的理念。


以上就是本篇博客的所有內容,感謝你的閱讀
如果覺得本篇文章對你有所幫助的話,不妨點個贊支持一下博主,拜托啦,這對我真的很重要。
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/81367.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/81367.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/81367.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android framework 中間件開發(三)

前兩篇我們講了中間件的開發和打包應用, Android framework 中間件開發(一) Android framework 中間件開發(二) 這邊我們來講一下在中間件中編寫JNI 1.新建C文件 找到frameworks\base\services\core\jni\路徑,新建一個cpp文件,文件名為com_android_server_DarkControlService.c…

深入了解linux系統—— 基礎IO(上)

文件 在之前學習C語言文件操作時&#xff0c;我們了解過什么是文件&#xff0c;這里簡單回顧一下&#xff1a; 文件存在磁盤中&#xff0c;文件有分為程序文件、數據文件&#xff1b;二進制文件和文本文件等。 詳細描述見文章&#xff1a;文件操作——C語言 文件在磁盤里&a…

Flink CDC—實時數據集成框架

Flink CDC 是一個基于流的數據集成工具&#xff0c;旨在為用戶提供一套功能更加全面的編程接口&#xff08;API&#xff09;&#xff0c;它基于數據庫日志的 CDC&#xff08;變更數據捕獲&#xff09;技術實現了統一的增量和全量數據讀取。 該工具使得用戶能夠以 YAML 配置文件…

ES(ES2023/ES14)最新更新內容,及如何減少內耗

截至2023年10月,JavaScript(ECMAScript)的最新版本是 ES2023(ES14)。 ES2023 引入了許多新特性,如findLast、toSorted等,同時優化了性能。通過減少全局變量、避免內存泄漏、優化循環、減少DOM操作、使用Web Workers、懶加載、緩存、高效數據結構和代碼壓縮,可以顯著降低…

常見的 Python 環境配置問題及解決方案

1. Python 環境配置的常見問題 初學者在配置 Python 環境時&#xff0c;可能會遇到以下幾類問題&#xff1a; 1.1 不同版本的兼容性 Python 目前有兩個主要版本系列&#xff1a;Python 2.x 和 Python 3.x。Python 2.x 已于 2020 年 1 月 1 日停止維護&#xff0c;因此強烈建…

day20-線性表(鏈表II)

一、調試器 1.1 gdb&#xff08;調試器&#xff09; 在程序指定位置停頓 1.1.1 一般調試 gcc直接編譯生成的是發布版&#xff08;Release&#xff09; gcc -g //-g調式版本&#xff0c;&#xff08;體積大&#xff0c;內部有源碼&#xff09;&#xff08;DeBug&#…

基于Spring Boot+Layui構建企業級電子招投標系統實戰指南

一、引言&#xff1a;重塑招投標管理新范式 在數字經濟浪潮下&#xff0c;傳統招投標模式面臨效率低、透明度不足、流程冗長等痛點。本文將以Spring Boot技術生態為核心&#xff0c;融合Mybatis持久層框架、Redis高性能緩存及Layui前端解決方案&#xff0c;構建一個覆蓋招標代理…

uniapp -- uCharts 儀表盤刻度顯示 0.9999999 這樣的值問題處理。

文章目錄 ??問題??解決方案??問題 在儀表盤上,23.8變成了 23.799999999999997 ??解決方案 formatter格式化問題 1:在 config-ucharts.js 或 config-echarts.js 配置對應的 formatter 方法 formatter: {yAxisDemo1: function (

git 對于已經追蹤,但沒有git add 的文件,撤回修改的方法

要撤銷對已追蹤文件的修改&#xff08;但尚未使用git add添加到暫存區&#xff09;&#xff0c;你可以使用以下幾種方法&#xff1a; 1. 使用 git restore (Git 2.23.0及更高版本) 這是較新版本Git中推薦的方式&#xff1a; # 撤銷單個文件的修改git restore <file># …

腳本語言Lua

本文來源 &#xff1a;騰訊元寶 Lua是一種輕量級、可嵌入的腳本語言&#xff0c;由巴西里約熱內盧天主教大學的Roberto Ierusalimschy、Waldemar Celes和Luiz Henrique de Figueiredo于1993年開發。其設計目標是嵌入應用程序中&#xff0c;提供靈活的擴展和定制功能。 主要特性…

ThingsBoard使用Cassandra部署時性能優化

1、概述 當遇到ThingsBoard設備數量特別多的時候,并且傳輸數據遙測點量特別大的時候,我們需要調整一下參數來進行優化,使其性能達到最佳的進行快速寫入。 注意:以下這些參數再系統部署的時候就需要規劃好配置,不能安裝好了再二次來進行配置。 2、Cassandra配置參數優化 …

Git Worktree 使用

新入職了一家公司&#xff0c;發現不同項目用的使用一個 git 倉庫管理。不久之后我看到這篇文章。 Git 的設計部??分是為了支持實驗。一旦你確定你的工作被安全地跟蹤&#xff0c;并且存在安全的狀態&#xff0c;以便在出現嚴重錯誤時可以恢復&#xff0c;你就不會害怕嘗試新…

維智定位 Android 定位 SDK

概述 維智 Android 定位 SDK是為 Android 移動端應用提供的一套簡單易用的定位服務接口&#xff0c;為廣大開發者提供融合定位服務。通過使用維智定位SDK&#xff0c;開發者可以輕松為應用程序實現極速、智能、精準、高效的定位功能。 重要&#xff1a;為了進一步加強對最終用…

【CSS】使用 CSS 繪制三角形

一、Border 邊框法&#xff08;最常用&#xff09; 原理&#xff1a;通過設置元素的寬高為 0&#xff0c;利用透明邊框相交形成三角形。 .triangle {width: 0;height: 0;border-left: 50px solid transparent; /* 左側邊框透明 */border-right: 50px solid transparent; /* …

RabbitMQ 快速上手:安裝配置與 HelloWorld 實踐(一)

一、引言 在當今分布式系統大行其道的技術浪潮下&#xff0c;各個服務之間的通信與協同變得愈發復雜。想象一下&#xff0c;一個電商系統在大促期間&#xff0c;訂單服務、庫存服務、支付服務、物流服務等眾多模塊需要緊密配合。如果沒有一種高效的通信機制&#xff0c;系統很容…

【deekseek】TCP Offload Engine

是的&#xff0c;TOE&#xff08;TCP Offload Engine&#xff09;通過專用硬件電路&#xff08;如ASIC或FPGA&#xff09;完整實現了TCP/IP協議棧&#xff0c;將原本由CPU軟件處理的協議計算任務完全轉移到網卡硬件中。其延遲極低的核心原因在于 硬件并行性、零拷貝架構 和 繞過…

JavaScript 的編譯與執行原理

文章目錄 前言&#x1f9e0; 一、JavaScript 編譯與執行過程1. 編譯階段&#xff08;發生在代碼執行前&#xff09;? 1.1 詞法分析&#xff08;Lexical Analysis&#xff09;? 1.2 語法分析&#xff08;Parsing&#xff09;? 1.3 語義分析與生成執行上下文 &#x1f9f0; 二…

WORD個人簡歷單頁326款模版分享下載

WORD個人簡歷模版下載&#xff1a;WORD個人簡歷模版https://pan.quark.cn/s/7e79a822c490

Android 中 顯示 PDF 文件內容(AndroidPdfViewer 庫)

PDFView 是一個用于在 Android 應用中顯示 PDF 文檔的庫。它提供了豐富的功能和靈活的配置選項&#xff0c;使得開發者能夠輕松地在應用中嵌入 PDF 閱讀器。 一、 添加依賴 在模塊的 build.gradle 文件中添加以下依賴&#xff1a; // pdfimplementation("com.github.bar…

微信小程序學習之搜索框

1、第一步&#xff0c;我們在index.json中引入vant中的搜索框控件&#xff1a; {"usingComponents": {"van-search": "vant/weapp/search/index"} } 2、第二步&#xff0c;直接在index.wxml中添加布局&#xff1a; <view class"index…