Redis 簡介
Redis 是完全開源免費的,遵守BSD協定,是一個高性能的key-value資料庫。
Redis 與其他 key - value 緩存産品有以下三個特點:
- Redis支援資料的持久化,可以将記憶體中的資料儲存在磁盤中,重新開機的時候可以再次加載進行使用。
- Redis不僅僅支援簡單的key-value類型的資料,同時還提供list,set,zset,hash等資料結構的存儲。
- Redis支援資料的備份,即master-slave模式的資料備份。
Redis 優勢
- 性能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
- 豐富的資料類型 – Redis支援二進制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 資料類型操作。
- 原子 – Redis的所有操作都是原子性的,同時Redis還支援對幾個操作全并後的原子性執行。
- 豐富的特性 – Redis還支援 publish/subscribe, 通知, key 過期等等特性。
Redis與其他key-value存儲有什麼不同?
- Redis有着更為複雜的資料結構并且提供對他們的原子性操作,這是一個不同于其他資料庫的進化路徑。Redis的資料類型都是基于基本資料結構的同時對程式員透明,無需進行額外的抽象。
- Redis運作在記憶體中但是可以持久化到磁盤,是以在對不同資料集進行高速讀寫時需要權衡記憶體,因為資料量不能大于硬體記憶體。在記憶體資料庫方面的另一個優點是,相比在磁盤上相同的複雜的資料結構,在記憶體中操作起來非常簡單,速度快,這樣Redis可以做很多内部複雜性很強的事情。同時,在磁盤格式方面他們是緊湊的以追加的方式産生的,因為他們并不需要進行随機通路。
redis 有五大資料類型
redis本質上一個key-value db,key的長度最好不要太長,道理很明顯占記憶體啊,而且查找的時候相對短key也更慢,
不過也不推薦過短的key,可讀性好即可
1.string類型
string是redis最基本的類型,而且string類型是二進制安全的。意思是redis的string可以包含任何資料。比如jpg圖檔或者序列化的對象
基本指令就是 set key value,get key ,使用場景:正常key-value緩存應用。例如某個查詢資料庫的接口經常被調用,假如傳回一個json對象,就可以利用json的stringify()和parse方法,來用string來做緩存
2.List類型
Lists 就是連結清單,略有資料結構知識的人都應該能了解其結構。使用Lists結構,我們可以輕松地實作最新消息排行等功能。Lists的另一個應用就是消息隊列,可以利用Lists的PUSH操作,将任務存在Lists中,然後工作線程再用POP操作将任務取出進行執行。Redis還提供了操作Lists中某一段的api,你可以直接查詢,删除Lists中某一段的元素。
redis的list類型其實就是一個每個子元素都是string類型的雙向連結清單。是以[lr]push和[lr]pop指令的算法時間複雜度都是O(1)另外list會記錄連結清單的長度。是以llen操作也是O(1).連結清單的最大長度是(2的32次方-1)。我們可以通過push,pop操作從連結清單的頭部或者尾部添加删除元素。這使得list既可以用作棧,也可以用作隊列。
常用場景:
取最新N個資料的操作
比如典型的取你網站的最新文章,通過下面方式,我們可以将最新的5000條評論的ID放在Redis的List集合中,并将超出集合部分從資料庫擷取
- 使用LPUSH latest.comments<ID>指令,向list集合中插入資料
- 插入完成後再用LTRIM latest.comments 0 5000指令使其永遠隻儲存最近5000個ID
3.Sets
Sets 就是一個集合,集合的概念就是一堆不重複值的組合。利用Redis提供的Sets資料結構,可以存儲一些集合性的資料。
案例:
在微網誌應用中,可以将一個使用者所有的關注人存在一個集合中,将其所有粉絲存在一個集合。Redis還為集合提供了求交集、并集、差集等操作,可以非常友善的實作如共同關注、共同喜好、二度好友等功能,對上面的所有集合操作,你還可以使用不同的指令選擇将結果傳回給用戶端還是存集到一個新的集合中。
Set是集合,概念和數學中個的集合基本類似,可以交集,并集,差集等等,set中的元素是沒有順序的。
4.Sorted Sets
和set一樣sorted set也是string類型元素的集合,不同的是每個元素都會關聯一個double類型的score。sorted set的實作是skip list和hash table的混合體
當元素被添加到集合中時,一個元素到score的映射被添加到hash table中,是以給定一個元素擷取score的開銷是O(1),另一個score到元素的映射被添加到skip list
并按照score排序,是以就可以有序的擷取集合中的元素。添加,删除操作開銷都是O(log(N))和skip list的開銷一緻,redis的skip list實作用的是雙向連結清單,這樣就
可以逆序從尾部取元素。sorted set最經常的使用方式應該是作為索引來使用.我們可以把要排序的字段作為score存儲,對象的id當元素存儲。和Sets相比,Sorted Sets增加了一個權重參數score,使得集合中的元素能夠按score進行有序排列,
使用場景:
1⃣️.比如一個存儲全班同學成績的Sorted Sets,其集合value可以是同學的學号,而score就可以是其考試得分,這樣在資料插入集合的時候,就已經進行了天然的排序。可以用Sorted Sets來做帶權重的隊列,比如普通消息的score為1,重要消息的score為2,然後工作線程可以選擇按score的倒序來擷取工作任務。讓重要的任務優先執行。
2⃣️.排行榜應用,取TOP N操作
這個需求與上面需求的不同之處在于,前面操作以時間為權重,這個是以某個條件為權重,比如按頂的次數排序,這時候就需要我們的sorted set出馬了,将你要排序的值設定成sorted set的score,将具體的資料設定成相應的value,每次隻需要執行一條ZADD指令即可。
3⃣️.需要精準設定過期時間的應用
比如你可以把上面說到的sorted set的score值設定成過期時間的時間戳,那麼就可以簡單地通過過期時間排序,定時清除過期資料了,不僅是清除Redis中的過期資料,你完全可以把Redis裡這個過期時間當成是對資料庫中資料的索引,用Redis來找出哪些資料需要過期删除,然後再精準地從資料庫中删除相應的記錄。
5.Hashs
在Memcached中,我們經常将一些結構化的資訊打包成hashmap,在用戶端序列化後存儲為一個字元串的值,比如使用者的昵稱、年齡、性别、積分等,這時候在需要修改其中某一項時,通常需要将所有值取出反序列化後,修改某一項的值,再序列化存儲回去。這樣不僅增大了開銷,也不适用于一些可能并發操作的場合(比如兩個并發的操作都需要修改積分)。而Redis的Hash結構可以使你像在資料庫中Update一個屬性一樣隻修改某一項屬性值。
redis hash是一個string類型的field和value的映射表.它的添加,删除操作都是O(1)(平均).hash特别适合用于存儲對象。相較于将對象的每個字段存成
單個string類型。将一個對象存儲在hash類型中會占用更少的記憶體,并且可以更友善的存取整個對象。省記憶體的原因是建立一個hash對象時開始是用zipmap(又稱為small hash)來存儲的。這個zipmap其實并不是hashtable,但是zipmap相比正常的hash實作可以節省不少hash本身需要的一些中繼資料存儲開銷。盡管zipmap的添加,删除,查找都是O(n),但是由于一般對象的field數量都不太多。是以使用zipmap也是很快的,也就是說添加删除平均還是O(1)。如果field或者value的大小超出一定限制後,redis會在内部自動将zipmap替換成正常的hash實作. 這個限制可以在配置檔案中指定