本章主要內容
? Redis 與其他軟體的相同之處和不同之處
? Redis 的用法
? 使用 Python 示例代碼與 Redis 進行簡單的互動
? 使用 Redis 解決實際問題
以下知識點決議來自于《Redis實戰》檔案其中的一部分!由于不影響觀看,只選取了其中的一部分來展示,
需要完整版的可以點擊這里!!暗號CSDN,獲取!
Redis 是一個遠程記憶體資料庫,它不僅性能強勁,而且還具有復制特性以及為解決問題而生
的獨一無二的資料模型,Redis 提供了 5 種不同型別的資料結構,各式各樣的問題都可以很自然
地映射到這些資料結構上:Redis 的資料結構致力于幫助用戶解決問題,而不會像其他資料庫那
樣,要求用戶扭曲問題來適應資料庫,除此之外,通過復制、持久化(persistence)和客戶端分
片(client-side sharding)等特性,用戶可以很方便地將 Redis 擴展成一個能夠包含數百 GB 資料、
每秒處理上百萬次請求的系統,
筆者第一次使用 Redis 是在一家公司里面,這家公司需要對一個保存了 6 萬個客戶聯系
方式的關系資料庫進行搜索,搜索可以根據名字、郵件地址、所在地和電話號碼來進行,每
次搜索需要花費 10~15 秒的時間,在花了一周時間學習 Redis 的基礎知識之后,我使用 Redis
重寫了一個新的搜索引擎,然后又花費了數周時間來仔細測驗這個新系統,使它達到生產級
別,最終這個新的搜索系統不僅可以根據名字、郵件地址、所在地和電話號碼等資訊來過濾
和排序客戶聯系方式,并且每次操作都可以在 50 毫秒之內完成,這比原來的搜索系統足足快
了 200 倍,閱讀本書可以讓你學到很多小技巧、小竅門以及使用 Redis 解決某些常見問題的
方法,
本章將介紹 Redis 的適用范圍,以及在不同環境中使用 Redis 的方法(比如怎樣跟不同的組
件和編程語言進行通信等);而之后的章節則會展示各式各樣的問題,以及使用 Redis 來解決這
些問題的方法,
第 1 章 初識 Redis
1.1 Redis 簡介
安裝 Redis 和 Python 附錄 A 介紹了快速安裝 Redis 和 Python 的方法,
在其他編程語言里面使用 Redis 本書只展示了使用 Python 語言撰寫的示例代碼,使用 Ruby、Java 和 JavaScript(Node.js)撰寫的示例代碼可以在這里找到:https://github.com/josiahcarlson/redis-in-action,使用 Spring 框架的讀者可以通過查看 http://www.springsource.org/spring-data/redis來學習如何在 Spring 框架中使用 Redis,
前面對于Redis資料庫的描述只說出了一部分真相,Redis是一個速度非常快的非關系數
據庫(non-relational database),它可以存盤鍵(key)與 5 種不同型別的值(value)之間的
映射(mapping),可以將存盤在記憶體的鍵值對資料持久化到硬碟,可以使用復制特性來擴
展讀性能,還可以使用客戶端分片
1.1.1 Redis 與其他資料庫和軟體的對比
來擴展寫性能,接下來的幾節將分別介紹Redis的這幾個特性,
如果你熟悉關系資料庫,那么你肯定寫過用來關聯兩個表的資料的 SQL 查詢 ,而 Redis 則屬于人們常說的 NoSQL 資料庫或者非關系資料庫:Redis 不使用表,它的資料庫也不會預定義或者強制去要求用戶對 Redis 存盤的不同資料進行關聯,
高性能鍵值快取服務器 memcached 也經常被拿來與 Redis 進行比較:這兩者都可用于存盤鍵值映射,彼此的性能也相差無幾,但是 Redis 能夠自動以兩種不同的方式將資料寫入硬碟,并且 Redis 除了能存盤普通的字串鍵之外,還可以存盤其他 4 種資料結構,而 memcached 只能存盤普通的字串鍵,這些不同之處使得 Redis 可以用于解決更為廣泛的問題,并且既可以用作主資料庫(primary database)使用,又可以作為其他存盤系統的輔助資料庫(auxiliary database)使用,
本書的后續章節會分別介紹將 Redis 用作主存盤(primary storage)和二級存盤(secondary storage)時的用法和查詢模式,一般來說,許多用戶只會在 Redis 的性能或者功能是必要的情況下,才會將資料存盤到 Redis 里面:如果程式對性能的要求不高,又或者因為費用原因而沒辦法將大量資料存盤到記憶體里面,那么用戶可能會選擇使用關系資料庫,或者其他非關系資料庫,在實際中,讀者應該根據自己的需求來決定是否使用 Redis,并考慮是將 Redis 用作主存盤還是輔
① 分片是一種將資料劃分為多個部分的方法,對資料的劃分可以基于鍵包含的 ID、基于鍵的散列值,或者
基于以上兩者的某種組合,通過對資料進行分片,用戶可以將資料存盤到多臺機器里面,也可以從多臺
機器里面獲取資料,這種方法在解決某些問題時可以獲得線性級別的性能提升,
助存盤,以及如何通過復制、持久化和事務等手段保證資料的完整性,
表 1-1 展示了一部分在功能上與 Redis 有重疊的資料庫服務器和快取服務器,從這個表可以
看出 Redis 與這些資料庫及軟體之間的區別, 
1.1.2 附加特性
在使用類似 Redis 這樣的記憶體資料庫時,一個首先要考慮的問題就是“當服務器被關閉時,服務器存盤的資料將何去何從呢?”Redis 擁有兩種不同形式的持久化方法,它們都可以用小而緊湊的格式將存盤在記憶體中的資料寫入硬碟:第一種持久化方法為時間點轉儲(point-in-time dump),轉儲操作既可以在“指定時間段內有指定數量的寫操作執行”這一條件被滿足時執行,又可以通過呼叫兩條轉儲到硬碟(dump-to-disk)命令中的任何一條來執行;第二種持久化方法將所有修改了資料庫的命令都寫入一個只追加(append-only)檔案里面,用戶可以根據資料的重要程度,將只追加寫入設定為從不同步(sync)、每秒同步一次或者每寫入一個命令就同步一次,
我們將在第 4 章中更加深入地討論這些持久化選項,另外,盡管 Redis 的性能很好,但受限于 Redis 的記憶體存盤設計,有時候只使用一臺 Redis服務器可能沒有辦法處理所有請求,因此,為了擴展 Redis 的讀性能,并為 Redis 提供故障轉移
5 (failover)支持 ,Redis 實作了主從復制特性:執行復制的從服務器會連接上主服務器,接收主服務器發送的整個資料庫的初始副本(copy);之后主服務器執行的寫命令,都會被發送給所有連接著的從服務器去執行,從而實時地更新從服務器的資料集,因為從服務器包含的資料會不斷地進行更新,所以客戶端可以向任意一個從服務器發送讀請求,以此來避免對主服務器進行集中式的訪問,我們將在第 4 章中更加深入地討論 Redis 從服務器,
1.1.3 使用 Redis 的理由
有 memcached 使用經驗的讀者可能知道,用戶只能用 APPEND 命令將資料添加到已有字串的末尾,memcached 的檔案中宣告,可以用 APPEND 命令來管理元素串列,這很好!用戶可以將元素追加到一個字串的末尾,并將那個字串當作串列來使用,但隨后如何洗掉這些元素呢?memcached 采用的辦法是通過黑名單(blacklist)來隱藏串列里面的元素,從而避免對元素執行讀取、更新、寫入(包括在一次資料庫查詢之后執行的 memcached 寫入)等操作,相反地,Redis 的 LIST 和 SET 允許用戶直接添加或者洗掉元素,使用 Redis 而不是 memcached 來解決問題,不僅可以讓代碼變得更簡短、更易懂、更易維護,而且還可以使代碼的運行速度更快(因為用戶不需要通過讀取資料庫來更新資料),除此之外,在其他許多情況下,Redis 的效率和易用性也比關系資料庫要好得多,
資料庫的一個常見用法是存盤長期的報告資料,并將這些報告資料用作固定時間范圍內的聚合資料(aggregates),收集聚合資料的常見做法是:先將各個行插入一個報告表里面,之后再通過掃描這些行來收集聚合資料,并根據收集到的聚合資料來更新聚合表中已有的那些行,之所以使用插入行的方式來存盤,是因為對于大部分資料庫來說,插入行操作的執行速度非常快(插入行只會在硬碟檔案末尾進行寫入),不過,對表里面的行進行更新卻是一個速度相當慢的操作,因為這種更新除了會引起一次隨機讀(random read)之外,還可能會引起一次隨機寫(random write),而在Redis里面,用戶可以直接使用原子的(atomic)INCR命令及其變種來計算聚合資料,并且因為Redis將資料存盤在記憶體里面 ①
① 客觀來講,memcached 也能用在這個簡單的場景里,但使用 Redis 存盤聚合資料有以下 3 個好處:
1、首先,使用 Redis 可以將彼此相關的聚合資料放在同一個結構里面,這樣訪問聚合資料就會變得更為容易;
2、其次,使用 Redis 可以將聚合資料放到有序集合里面,構建出一個實時的排行榜;
3、最后,Redis 的聚合資料可以是整數或者浮點數,而 memcached 的聚合資料只能是整數,而且發送給Redis的命令請求并不需要經過典型的查詢分析器(parser)或者查詢優化器(optimizer)進行處理,所以對Redis存盤的資料執行隨機寫的速度總是非常迅速的,
使用 Redis 而不是關系資料庫或者其他硬碟存盤資料庫,可以避免寫入不必要的臨時資料,也免去了對臨時資料進行掃描或者洗掉的麻煩,并最終改善程式的性能,雖然上面列舉的都是一些簡單的例子,但它們很好地證明了“工具會極大地改變人們解決問題的方式”這一點,
1.2 Redis 資料結構簡介
正如之前的表 1-1 所示,Redis 可以存盤鍵與 5 種不同資料結構型別之間的映射,這 5 種數
據結構型別分別為 STRING(字串)、LIST(串列)、SET(集合)、HASH(散列)和 ZSET(有序集合),有一部分 Redis 命令對于這 5 種結構都是通用的,如 DEL、TYPE、RENAME 等;但也有一部分 Redis 命令只能對特定的一種或者兩種結構使用,第 3 章將對 Redis 提供的命令進行更深入的介紹,
大部分程式員應該都不會對 Redis 的 STRING、LIST、HASH 這 3 種結構感到陌生,因
為它們和很多編程語言內建的字串、串列和散列等結構在實作和語意(semantics)方面都
非常相似,有些編程語言還有集合資料結構,在實作和語意上類似于 Redis 的 SET,ZSET 在
某種程度上是一種 Redis 特有的結構,但是當你熟悉了它之后,就會發現它也是一種非常有
用的結構,表 1-2 對比了 Redis 提供的 5 種結構,說明了這些結構存盤的值,并簡單介紹了
它們的語意,
命令串列 本節在介紹每個資料型別的時候,都會在一個表格里面展示一小部分處理這些資料結 構的命令,之后的第 3會展示一個更詳細(但仍不完整)的命令串列,完整的 Redis 命令串列 可以http://redis.io/commands 找到,
這一節將介紹如何表示 Redis 的這 5 種結構,并且還會介紹 Redis 命令的使用方法,從而為本書的后續內容打好基礎,本書展示的所有示例代碼都是用 Python 寫的,如果讀者已經按照附錄 A 里面描述的方法安裝好了 Redis,那么應該也已經安裝好了 Python,以及在 Python 里面使用Redis 所需的客戶端庫,只要讀者在電腦里面安裝了 Redis、Python 和 redis-py 庫,就可以在閱讀本書的同時,嘗試執行書中展示的示例代碼了,
請安裝 Redis 和 Python 在閱讀后續內容之前,請讀者先按照附錄 A 中介紹的方法安裝 Redis 和Python,如果讀者覺得附錄 A 描述的安裝方法過于復雜,那么這里有一個更簡單的方法,但這 個方法只能用于 Debian系統(或者該系統的衍生系統):從 http://redis.io/download 下載 Redis 的 壓縮包,解壓壓縮包,執行 make&& sudo make install,之后再執行 sudo python -m easy_install redis hiredis(hiredis 是可選的,它是一個使用 C 語言撰寫的高性能 Redis 客戶端),
如果讀者熟悉程序式編程語言或者面向物件編程語言,那么即使沒有使用過 Python,應該也
可以看懂 Python 代碼,另一方面,如果讀者決定使用其他編程語言來操作 Redis,那么就需要自
己來將本書的 Python 代碼翻譯成正在使用的語言的代碼,
使用其他語言撰寫的示例代碼 盡管沒有包含在書中,但本書展示的 Python 示例代碼已經被翻譯成 了 Ruby 代碼、Java 代碼和JavaScript 代碼,這些翻譯代碼可以在 https://github.com/josiahcarlson/redis-in-action 下載到,跟 Python 撰寫的示例代碼一樣,這些翻譯代碼也包含相應的注釋,方便讀 者參考,
為了讓示例代碼盡可能地簡單,本書會盡量避免使用 Python 的高級特性,并使用函式而不
是類或者其他東西來執行 Redis 操作,以此來將焦點放在使用 Redis 解決問題上面,而不必過多
地關注 Python 的語法,本節將使用 redis-cli 控制臺與 Redis 進行互動,首先,讓我們來了解一下
Redis 中最簡單的結構:STRING,
1.2.1 Redis 中的字串
Redis 的字串和其他編程語言或者其他鍵值存盤提供的字串非常相似,本書在使用
圖片表示鍵和值的時候,通常會將鍵名(key name)和值的型別放在方框的頂部,并將值
放在方框的里面,圖 1-1 以鍵為 hello、值為 world 的字串為例,分別標記了方框的各
個部分,

字串擁有一些和其他鍵值存盤相似的命令,比如 GET(獲取值)、SET(設定值)和 DEL(洗掉值),如果讀者已經按照附錄 A 中給出的方法安裝了 Redis,那么可以根據代碼清單 1-1 展示的例子,嘗試使用 redis-cli 執行 SET、GET 和 DEL,表 1-3 描述了這 3 個命令的基本用法,
使用 redis-cli 為了讓讀者在一開始就能便捷地與 Redis 進行互動,本章將使用 redis-cli 這個互動式 客戶端來介紹
Redis 命令,
除了能夠 GET、SET 和 DEL 字串值之外,Redis 還提供了一些可以對字串的其中一部分內容進行讀取和寫入的命令,以及一些能對字串存盤的數值執行自增或者自減操作的命令,第 3 章
將對這些命令進行介紹,但是在此之前,我們還有許多基礎知識需要了解,下面來看一下 Redis 的串列及其功能,
1.2.2 Redis 中的串列
Redis 對鏈表(linked-list)結構的支持使得它在鍵值存盤的世界中獨樹一幟,一個串列結構可以有序地存盤多個字串,和表示字串時使用的方法一樣,本節使用帶有標簽的方框來表示串列,并將串列包含的元素放在方框里面,圖 1-2 展示了一個這樣的示例,
Redis 串列可執行的操作和很多編程語言里面的串列操作非常相似:LPUSH 命令和 RPUSH 命令分別用于將元素推入串列的左端(left end)和右端(right end);LPOP 命令和 RPOP 命令分別用于從串列的左端和右端彈出元素;LINDEX 命令用于獲取串列在給定位置上的一個元素;LRANGE 命令用于獲取串列在給定范圍上的所有元素,代碼清單 1-2 展示了一些串列命令的使用示例,表 1-4 簡單介紹了示例中用到的各個命令,
即使 Redis 的串列只支持以上提到的幾個命令,它也已經可以用來解決很多問題了,但 Redis 并沒
有就此止步—除了上面提到的命令之外,Redis 串列還擁有從串列里面移除元素的命令、將元素插入
串列中間的命令、將串列修剪至指定長度(相當于從串列的其中一端或者兩端移除元素)的命令,以
及其他一些命令,第 3 章將介紹許多串列命令,但是在此之前,讓我們先來了解一下 Redis 的集合,
1.2.3 Redis 的集合
Redis 的集合和串列都可以存盤多個字串,它們之間的不同在于,串列可以存盤多個相同的字串,而
集合則通過使用散串列來保證自己存盤的每個字串都是各不相同的(這些散串列只有鍵,但沒有與鍵相關聯的值),本書表示集合的方法和表示串列的方法基本相同,圖 1-3 展示了一個包含 3 個元素的示例集合,
因為 Redis 的集合使用無序(unordered)方式存盤元素,所以用戶不能像使用串列那樣,將元素推入集合
的某一端,或者從集合的某一端彈出元素,不過用戶可以使用 SADD 命令將元素添加到集合,或者使用 SREM命令從集合里面移除元素,另外還可以通過 SISMEMBER 命令快速地檢查一個元素是否已經存在于集合中,或者使用 SMEMBERS 命令獲取集合包含的所有元素(如果集合包含的元素非常多,那么 SMEMBERS 命令的執行速度可能會很慢,所以請謹慎地使用這個命令),代碼清單 1-3 展示了一些集合命令的使用示例,表 1-5 簡單介紹了代碼清單里面用到的各個命令,

跟字串和串列一樣,集合除了基本的添加操作和移除操作之外,還支持很多其他操作,比
如 SINTER、SUNION、SDIFF 這 3 個命令就可以分別執行常見的交集計算、并集計算和差集計
算,第 3 章將對集合的相關命令進行更詳細的介紹,另外第 7 章還會展示如何使用集合來解決多
個問題,不過別心急,因為在 Redis 提供的 5 種資料結構中,還有兩種我們尚未了解,讓我們先
來看看 Redis 的散列,
1.2.4 Redis 的散列
Redis 的散列可以存盤多個鍵值對之間的映射,和字串一樣,散列存盤的值既可以是字符
串又可以是數字值,并且用戶同樣可以對散列存盤的數字值執行自增操作或者自減操作,圖 1-4
展示了一個包含兩個鍵值對的散列,
散列在很多方面就像是一個微縮版的 Redis,不少字串命令都有相應的散列版本,代碼清
單 1-4 展示了怎樣對散列執行插入元素、獲取元素和移除元素等操作,表 1-6 簡單介紹了代碼清
單里面用到的各個命令,

熟悉檔案資料庫的讀者可以將 Redis 的散列看作是檔案資料庫里面的檔案,而熟悉關系資料庫的
讀者則可以將 Redis 的散列看作是關系資料庫里面的行,因為散列、檔案和行這三者都允許用戶同時訪
問或者修改一個或多個域(field),最后,讓我們來了解一下 Redis 的 5 種資料結構中的最后一種:有序集合,
1.2.5 Redis 的有序集合
有序集合和散列一樣,都用于存盤鍵值對:有序集合的鍵被稱為成員(member),每個成員都是各不相同的;而有序集合的值則被稱為分值(score),分值必須為浮點數,有序集合是 Redis 里面唯一一個既可以根據成員訪問元素(這一點和散列一樣),又可以根據分值以及分值的排列順序來訪問元素的結構,圖 1-5 展示了一個包含兩個元素的有序集合示例,
和 Redis 的其他結構一樣,用戶可以對有序集合執行添加、移除和獲取等操作,代碼清單 1-5
展示了這些操作的執行示例,表 1-7 簡單介紹了代碼清單里面用到的各個命令,

現在讀者應該已經知道有序集合是什么和它能干什么了,到目前為止,我們基本了解了 Redis
提供的 5 種結構,接下來的一節將展示如何通過結合散列的資料存盤能力和有序集合內建的排
序能力來解決一個常見的問題,
以上知識點決議來自于《Redis實戰》檔案其中的一部分!由于不影響觀看,只選取了其中的一部分來展示,
需要完整版的可以點擊這里!!暗號CSDN,找群主獲取!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/231722.html
標籤:Java
