日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

深入剖析Redis系列(五) - Redis数据结构之字符串

發布時間:2023/12/6 数据库 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入剖析Redis系列(五) - Redis数据结构之字符串 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

字符串類型 是 Redis 最基礎的數據結構。字符串類型 的值實際可以是 字符串簡單復雜 的字符串,例如 JSON、XML)、數字(整數、浮點數),甚至是 二進制(圖片、音頻、視頻),但是值最大不能超過 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 命令有幾個選項:

  • ex seconds:為 設置 秒級過期時間。
  • px milliseconds:為 設置 毫秒級過期時間。
  • nx:鍵必須 不存在,才可以設置成功,用于 添加。
  • xx:與 nx 相反,鍵必須 存在,才可以設置成功,用于 更新。
  • 除了 set 選項,Redis 還提供了 setex 和 setnx 兩個命令:

    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 ...]

    通過下面操作 批量獲取 鍵 a、b、c、d 的值:

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

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

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

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

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

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

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

    操作時間
    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

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

    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

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

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

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

    2. 內部編碼

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

    • int:8 個字節的 長整型

    • 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 開發與運維》


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

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

    總結

    以上是生活随笔為你收集整理的深入剖析Redis系列(五) - Redis数据结构之字符串的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。