深入剖析Redis系列(五) - Redis數據結構之字符串

前言

字符串類型Redis 最基礎的數據結構。字符串類型 的值實際可以是 字符串簡單復雜 的字符串,例如 JSONXML)、數字(整數、浮點數),甚至是 二進制(圖片、音頻、視頻),但是值最大不能超過 512MB

其他文章

  • 深入剖析Redis系列(一) - Redis入門簡介與主從搭建

  • 深入剖析Redis系列(二) - Redis哨兵模式與高可用集群

  • 深入剖析Redis系列(三) - Redis集群模式搭建與原理詳解

  • 深入剖析Redis系列(四) - Redis數據結構與全局命令概述

  • 深入剖析Redis系列(五) - Redis數據結構之字符串

  • 深入剖析Redis系列(六) - Redis數據結構之哈希

  • 深入剖析Redis系列(七) - Redis數據結構之列表

  • 深入剖析Redis系列(八) - Redis數據結構之集合

正文

1. 相關命令

1.1. 常見命令

1.1.1. 設置值

set key value [ex seconds] [px milliseconds] [nx|xx]

set 命令有幾個選項:

  1. ex seconds:為 設置 秒級過期時間
  2. px milliseconds:為 設置 毫秒級過期時間
  3. nx:鍵必須 不存在,才可以設置成功,用于 添加
  4. xx:與 nx 相反,鍵必須 存在,才可以設置成功,用于 更新

除了 set 選項,Redis 還提供了 setexsetnx 兩個命令:

setex key seconds value setnx key value

  • setex:設定鍵的值,并指定此鍵值對應的 有效時間
127.0.0.1:6379> setex key1 5 value1
OK
127.0.0.1:6379> get key1
"value1"
127.0.0.1:6379> get key1
(nil)復制代碼
  • setnx:鍵必須 不存在,才可以設置成功。如果鍵已經存在,返回 0
127.0.0.1:6379> set key2 value1
OK
127.0.0.1:6379> setnx key2 value2
(integer) 1
127.0.0.1:6379> get key2
"value1"
復制代碼

1.1.2. 獲取值

get key

如果要獲取的 鍵不存在,則返回 nil)。

127.0.0.1:6379> get not_exist_key
(nil)
復制代碼

1.1.3. 批量設置值

mset key value [key value ...]

下面操作通過 mset 命令一次性設置 4鍵值對

127.0.0.1:6379> mset a 1 b 2 c 3 d 4
OK
復制代碼

1.1.4. 批量獲取值

mget key [key ...]

通過下面操作 批量獲取abcd 的值:

127.0.0.1:6379> mget a b c d
1) "1"
2) "2"
3) "3"
4) "4"
復制代碼

批量操作 命令,可以有效提高 開發效率,假如沒有 mget 這樣的命令,要執行 nget 命令的過程和 耗時 如下:

n次get時間 = n次網絡時間 + n次命令時間

使用 mget 命令后,執行 nget 命令的過程和 耗時 如下:

n次get時間 = 1次網絡時間 + n次命令時間

Redis 可以支撐 每秒數萬讀寫操作,但這指的是 Redis 服務端 的處理能力,對于 客戶端 來說,一次命令除了 命令時間 還是有 網絡時間

假設 網絡時間1 毫秒,命令時間為 0.1 毫秒(按照每秒處理 1 萬條命令算),那么執行 1000get 命令和 1mget 命令的區別如表所示:

操作時間
1000次get操作1000 * 1 + 1000 * 0.1 = 1100ms = 1.1s
1次mget操作1 * 1 + 1000 * 0.1 = 101ms = 0.101s

1.1.5. 計數

incr key

incr 命令用于對值做 自增操作,返回結果分為三種情況:

  • 值不是 整數,返回 錯誤
  • 值是 整數,返回 自增 后的結果。
  • 鍵不存在,按照值為 0 自增,返回結果為 1
127.0.0.1:6379> exists key
(integer) 0
127.0.0.1:6379> incr key
(integer) 1
復制代碼

除了 incr 命令,Redis 還提供了 decr自減)、incrby自增指定數字)、decrby自減指定數字)、incrbyfloat自增浮點數)等命令操作:

decr key incrby key increment decrby key decrement incrbyfloat key increment

很多 存儲系統編程語言 內部使用 CAS 機制實現 計數功能,會有一定的 CPU 開銷。但在 Redis 中完全不存在這個問題,因為 Redis單線程架構,任何命令到了 Redis 服務端 都要 順序執行

1.2. 不常用命令

1.2.1. 追加值

append key value

append 可以向 字符串尾部 追加值。

127.0.0.1:6379> get key
"redis"
127.0.0.1:6379> append key world
(integer) 10
127.0.0.1:6379> get key
"redisworld"
復制代碼

1.2.2. 字符串長度

strlen key

比如說,當前值為 redisworld,所以返回值為 10

127.0.0.1:6379> get key
"redisworld"
127.0.0.1:6379> strlen key
(integer) 10
復制代碼

1.2.3. 設置并返回原值

getset key value

getsetset 一樣會 設置值,但是不同的是,它同時會返回 鍵原來的值,例如:

127.0.0.1:6379> getset hello world
(nil)
127.0.0.1:6379> getset hello redis
"world"
復制代碼

1.2.4. 設置指定位置的字符

setrange key offeset value

下面操作將值由 pest 變為了 best

127.0.0.1:6379> set redis pest
OK
127.0.0.1:6379> setrange redis 0 b
(integer) 4
127.0.0.1:6379> get redis
"best"
復制代碼

1.2.5. 獲取部分字符串

getrange key start end

startend 分別是 開始結束偏移量偏移量0 開始計算,例如獲取值 best前兩個字符 的命令如下:

127.0.0.1:6379> getrange redis 0 1
"be"
復制代碼

最后給出 字符串 類型命令的 時間復雜度 說明:

2. 內部編碼

字符串 類型的 內部編碼3 種:

  • int8 個字節的 長整型

  • embstr小于等于 39 個字節的字符串。

  • raw大于 39 個字節的字符串。

Redis 會根據當前值的 類型長度 決定使用哪種 內部編碼實現

  • 整數類型
127.0.0.1:6379> set key 8653
OK
127.0.0.1:6379> object encoding key
"int"
復制代碼
  • 短字符串
#小于等于39個字節的字符串:embstr
127.0.0.1:6379> set key "hello,world"
OK
127.0.0.1:6379> object encoding key
"embstr"
復制代碼
  • 長字符串
#大于39個字節的字符串:raw
127.0.0.1:6379> set key "one string greater than 39 byte........."
OK
127.0.0.1:6379> object encoding key
"raw"
127.0.0.1:6379> strlen key
(integer) 40
復制代碼

3. 典型使用場景

3.1. 緩存功能

下面是一種比較典型的 緩存 使用場景,其中 Redis 作為 緩存層MySQL 作為 存儲層,絕大部分請求的數據都是從 Redis 中獲取。由于 Redis 具有支撐 高并發 的特性,所以緩存通常能起到 加速讀寫降低后端壓力 的作用。

整個功能的偽代碼如下:

public UserInfo getUserInfo(long id) {String userRedisKey = "user:info:" + id;String value = redis.get(userRedisKey);UserInfo userInfo;    if (value != null) {userInfo = deserialize(value);     } else {        userInfo = mysql.get(id);   if (userInfo != null) { redis.setex(userRedisKey, 3600, serialize(userInfo));}return userInfo;}
}
復制代碼

3.2. 計數

許多應用都會使用 Redis 作為 計數 的基礎工具,它可以實現 快速計數查詢緩存 的功能,同時數據可以 異步落地 到其他 數據源。一般來說,視頻播放數系統,就是使用 Redis 作為 視頻播放數計數 的基礎組件,用戶每播放一次視頻,相應的視頻播放數就會自增 1

public long incrVideoCounter (long id) {String key = "video:playCount:" + id;return redis.incr(key);
}
復制代碼

實際上,一個真實的 計數系統 要考慮的問題會很多:防作弊、按照 不同維度 計數,數據持久化底層數據源等。

3.3. 共享Session

一個 分布式 Web 服務將用戶的 Session 信息(例如 用戶登錄信息)保存在 各自 的服務器中。這樣會造成一個問題,出于 負載均衡 的考慮,分布式服務 會將用戶的訪問 均衡 到不同服務器上,用戶 刷新一次訪問 可能會發現需要 重新登錄,這個問題是用戶無法容忍的。

為了解決這個問題,可以使用 Redis 將用戶的 Session 進行 集中管理。在這種模式下,只要保證 Redis高可用擴展性的,每次用戶 更新 或者 查詢 登錄信息都直接從 Redis 中集中獲取。

3.4. 限速

很多應用出于安全的考慮,會在每次進行登錄時,讓用戶輸入 手機驗證碼,從而確定是否是用戶本人。但是為了 短信接口 不被 頻繁訪問,會 限制 用戶每分鐘獲取 驗證碼 的頻率。例如一分鐘不能超過 5 次,如圖所示:

此功能可以使用 Redis 來實現,偽代碼如下:

String phoneNum = "138xxxxxxxx";
String key = "shortMsg:limit:" + phoneNum;
// SET key value EX 60 NX
boolean isExists = redis.set(key, 1, "EX 60", "NX");
if (isExists != null || redis.incr(key) <= 5) {// 通過
} else {// 限速
}
復制代碼

上述就是利用 Redis 實現了 限速功能,例如 一些網站 限制一個 IP 地址不能在 一秒鐘之內 訪問超過 n 次也可以采用 類似 的思路。

小結

本文簡單的介紹了 Redis字符串數據結構基本命令內部編碼相關應用場景

參考

《Redis 開發與運維》


歡迎關注技術公眾號: 零壹技術棧

本帳號將持續分享后端技術干貨,包括虛擬機基礎,多線程編程,高性能框架,異步、緩存和消息中間件,分布式和微服務,架構學習和進階等學習資料和文章。

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

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

相關文章

全新升級的AOP框架Dora.Interception[6]: 框架設計和實現原理

本系列前面的五篇文章主要介紹Dora.Interception的編程模式以及對它的擴展定制&#xff0c;現在我們來聊聊它的設計和實現原理。目錄一、調用鏈抽象二、基于約定的攔截器定義三、基于調用上下文的依賴注入容器四、攔截器的提供五、調用鏈的構建六、方法攔截的實現原理七、依賴注…

activemq 安全連接

一、定義用戶組1.1 simpleAuthenticationPlugin通過在activemq.xml中配置用戶組<plugins> <simpleAuthenticationPlugin> <users> <authenticationUser username"admin" password"password" groups"admins,publishers,consumer…

React Native在Android當中實踐(五)——常見問題

React Native在Android當中實踐&#xff08;一&#xff09;——背景介紹 React Native在Android當中實踐&#xff08;二&#xff09;——搭建開發環境 React Native在Android當中實踐&#xff08;三&#xff09;——集成到Android項目當中 React Native在Android當中實踐&#…

完成登錄與注冊頁面的前端

完成登錄與注冊頁面的HTMLCSSJS&#xff0c;其中的輸入項檢查包括&#xff1a; 用戶名6-12位 首字母不能是數字 只能包含字母和數字 密碼6-12位 注冊頁兩次密碼是否一致 JS&#xff1a; function fnLogin() {var uSer document.getElementById("user");var pAss do…

mysql505復位密碼_mysql5 如何復位根用戶密碼[官方文檔]

如何復位根用戶密碼如果你從未為MySQL設置根用戶密碼&#xff0c;服務器在以根用戶身份進行連接時不需要密碼。但是&#xff0c;建議你為每個賬戶設置密碼如果你以前設置了根用戶密碼&#xff0c;但卻忘記了該密碼&#xff0c;可設置新的密碼。下述步驟是針對Windows平臺的。在…

WPF效果第二百零一篇之實現合并單元格

早一段時間又一次出差青海省西寧市;回來又是總結又是各種瑣事,也沒顧得上去分享點東西;大周末的就在家分享一下,這二天再次基于ListBox實現的合并單元格的效果:1、ListBox嵌套ListBox的前臺布局:<ListBox ItemsSource"{Binding LCPListData}" x:Name"Manufac…

轉載 maven 詳解 http://www.cnblogs.com/binyue/p/4729134.html

--聲明規范 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <!--聲…

ASP.NET Core中使用EasyCaching作為緩存抽象層

簡介做后端開發&#xff0c;緩存應該是天天在用&#xff0c;很多時候我們的做法是寫個幫助類&#xff0c;然后用到的時候調用一下。這種只適合簡單層次的應用&#xff1b;一旦涉及到接口實現調整之類的&#xff0c;這種強耦合的做法很不合適。有些其他的功能又要去重復造輪子。…

mysql qps如何查看_mysql狀態查看 QPS/TPS/緩存命中率查看

運行中的mysql狀態查看對正在運行的mysql進行監控&#xff0c;其中一個方式就是查看mysql運行狀態。(1)QPS(每秒Query量)QPS Questions(or Queries) / uptimemysql > show global status like Question%;mysql > show global status like uptime%;(2)TPS(每秒事務量…

visual studio開啟多核編譯方法

先按http://blog.csdn.net/acaiwlj/article/details/50240625的方法進行了VS多線程的啟動。 原本以為按以下步驟設置就OK了&#xff0c;但是編譯中無意間發些了一個warning&#xff1a;“/Gm”與多處理不兼容&#xff1b;忽略 /MP 開關&#xff01;&#xff01;&#xff01;&am…

聊聊storm nimbus的LeaderElector

為什么80%的碼農都做不了架構師&#xff1f;>>> 序 本文主要研究一下storm nimbus的LeaderElector Nimbus org/apache/storm/daemon/nimbus/Nimbus.java public static void main(String[] args) throws Exception {Utils.setupDefaultUncaughtExceptionHandler();…

Android框架式編程之BufferKnife

BufferKnife作為框架式編程的重要組成部分&#xff0c;使用BufferKnife能夠極大的精簡View層面的代碼量&#xff0c;并為MVP/MVC方式提供輔助。 一、配置 compile com.jakewharton:butterknife:(insert latest version) annotationProcessor com.jakewharton:butterknife-compi…

如果我去深圳,你會見我嗎

▲圖/ 深圳夜景初次見易小姐&#xff0c;還是21年的春節回老家的時候。想來20年因為疫情沒有回家&#xff0c;家母幾次三番電話里頭表達的思念以及建議一些不靠譜的回家計劃&#xff0c;著實有些不忍&#xff0c;確實有似“兒行千里母擔憂”之理&#xff0c;索性拿著年假和加班…

CodeForces - 1059D(二分+誤差)

鏈接&#xff1a;CodeForces - 1059D 題意&#xff1a;給出笛卡爾坐標系上 n 個點&#xff0c;求與 x 軸相切且覆蓋了所有給出點的圓的最小半徑。 題解&#xff1a;二分半徑即可。判斷&#xff1a;假設當前二分到的半徑是 R &#xff0c;因為要和 x 軸相切&#xff0c;所以圓心…

pureref 平移用不了_關于參考圖管理神器 PureRef 的一些快捷鍵

PureRef 的一些快捷鍵 軟件下載&#xff1a;點擊這里控制(配合左鍵)窗口內鼠標左鍵     框選窗口邊鼠標左鍵     調整窗口大小鼠標中鍵 或 按住Alt     移動畫布鼠標滾輪 或 按住Z     縮放畫布按住S     查看目標位置顏色信息(可復制16進制顏色…

Windows 10 版本信息

Windows 10 版本信息 原文 https://technet.microsoft.com/zh-cn/windows/release-info Windows 10 版本信息 Microsoft 已更新其服務模型。 半年頻道每年發布兩次功能更新&#xff0c;時間大概在 3 月和 9 月&#xff0c;每個版本的服務時間線為 18 個月。 從 Windows 10 版本…

開源輕量的 .NET 監控工具 - 看門狗

你好&#xff0c;這里是 Dotnet 工具箱&#xff0c;定期分享 Dotnet 有趣&#xff0c;實用的工具或組件&#xff0c;希望對您有用&#xff01;簡介WatchDog 是一個使用 C# 開發的開源的輕量監控工具&#xff0c;它可以記錄和查看 ASP.Net Core Web 和 WebApi 的實時消息、事件、…

python讀取oracle數據庫性能_用python對oracle進行簡單性能測試

一、概述dba在工作中避不開的兩個問題&#xff0c;sql使用綁定變量到底會有多少的性能提升&#xff1f;數據庫的審計功能如果打開對數據庫的性能會產生多大的影響&#xff1f;最近恰好都碰到了&#xff0c;索性做個實驗。sql使用綁定變量對性能的影響開通數據庫審計功能對性能的…

BZOJ 3231: [Sdoi2008]遞歸數列 (JZYZOJ 1353) 矩陣快速冪

http://www.lydsy.com/JudgeOnline/problem.php?id3231和斐波那契一個道理在最后加一個求和即可1 #include<cstdio>2 #include<cstring>3 #include<iostream>4 //using namespace std;5 const int maxn10010;6 const double eps1e-8;7 long long modn;8 lon…

馬斯克的火箭上天了,SpaceX開源項目也登上了熱榜!

python知識手冊SpaceX于美國東部時間5月30日下午3&#xff1a;22分將兩位美國宇航員送往國際空間站&#xff0c;雖然這只是Demo任務&#xff0c;但SpaceX已經以其卓越工程優勢、低廉的發射成本贏得了全球航天產業的信賴。同時也是除美俄中這些航天國家隊以外&#xff0c;唯一獨…