您好,登錄后才能下訂單哦!
本篇內容主要講解“Redis的詳細介紹和應用”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Redis的詳細介紹和應用”吧!
Redis
是一個開源(BSD許可
)的內存中的數據結構存儲,用作數據庫、緩存和消息中間件。它支持多種數據結構,如字符串
、哈希表
、列表
、無序集合
、有序集合
的范圍查詢,位圖
、基數統計
和地理空間索引
的與查詢。Redis內置復制
、Lua腳本
、LRU回收
、事務
和不同級別的磁盤持久化
,并通過哨兵
和自動分區
提供高可用性集群。
純內存數據庫,瓶頸不在內存,在于網絡IO
單線程,避免頻繁切換上下文
異步阻塞I/O(多路復用)
快照
優點:適合備份、還原、恢復數據快、最大化 Redis 的性能
缺點:兩次快照間的數據會丟失、數據集比較龐大時, fork()
可能會非常耗時
日志
優點:數據完整性高、可讀性高、可重寫(重寫后的新 AOF 文件包含了恢復當前數據集所需的最小命令集合)
缺點:體積大、慢于RDB、有bug
multi
開啟事務,exec
執行事務
可以看到,redis事務實現原理是將要執行的命令,存儲到一個隊列中,依次執行,報錯時停止并取消事務,不報錯則提交事務。
例外:不會回滾的情況:
當一個事務中某一條(多條)命令加入隊列不報錯,執行時才會報錯,則redis會忽略錯誤繼續執行。
使用watch
監視一個(或多個) key ,如果在事務執行之前這個(或這些) key 被其他命令所改動,那么事務將被打斷。當exec
被調用時, 不管事務是否成功執行, 對所有鍵的監視都會被取消。或者調用unwatch
手動取消監控。
pipeline通過減少客戶端與redis的通信次數來實現降低往返延時時間,而且Pipeline 實現的原理是隊列,而隊列的原理是時先進先出,這樣就保證數據的順序性。
適用場景:批量操作、可靠性要求不高、
Lua是一個高效的輕量級腳本語言,用標準C語言編寫并以源代碼形式開放, 其設計目的是為了嵌入應用程序中,從而為應用程序提供靈活的擴展和定制功能,從定義上來說, Redis 中的腳本本身就是一種事務, 所以任何在事務里可以完成的事, 在腳本里面也能完成。 并且一般來說, 使用腳本要來得更簡單,并且速度更快。
通過lua腳本可以原子執行多條redis命令
執行lua腳本期間,會阻塞所有命令操作
減少網絡開銷,在Lua腳本中可以把多個命令放在同一個腳本中運行
原子操作,redis會將整個腳本作為一個整體執行,中間不會被其他命令插入。換句話說,編寫腳本的過程中無需擔心會出現競態條件
復用性,客戶端發送的腳本會永遠存儲在redis中,這意味著其他客戶端可以復用這一腳本來完成同樣的邏輯
默認支持16個數據庫;可以理解為一個命名空間
跟關系型數據庫不一樣的點
redis不支持自定義數據庫名詞
每個數據庫不能單獨設置授權
每個數據庫之間并不是完全隔離的。 可以通過flushall命令清空redis實例面的所有數據庫中的數據
通過 select dbid 去選擇不同的數據庫命名空間 。 dbid的取值范圍默認是0 -15
Redis Cluster中,Sharding采用slot(槽)的概念,一共分成16384個槽,這有點兒類似前面講的pre sharding思路。對于每個進入Redis的鍵值對,根據key進行散列,分配到這16384個slot中的某一個中。使用的hash算法也比較簡單,就是CRC16后16384取模。Redis集群中的每個node(節點)負責分攤這16384個slot中的一部分,也就是說,每個slot都對應一個node負責處理。當動態添加或減少node節點時,需要將16384個槽做個再分配,槽中的鍵值也要遷移。當然,這一過程,在目前實現中,還處于半自動狀態,需要人工介入。Redis集群,要保證16384個槽對應的node都正常工作,如果某個node發生故障,那它負責的slots也就失效,整個集群將不能工作。為了增加集群的可訪問性,官方推薦的方案是將node配置成主從結構,即一個master主節點,掛n個slave從節點。這時,如果主節點失效,Redis Cluster會根據選舉算法從slave節點中選擇一個上升為主節點,整個集群繼續對外提供服務。這非常類似服務器節點通過Sentinel監控架構成主從結構,只是Redis Cluster本身提供了故障轉移容錯的能力。
redis sharding
codis
twemproxy
默認存儲最大容量為512M
常用命令:set、get、incr、decr、append、strlen、mget、setnx
set+get:緩存、單點登錄
bitmap:用戶上線次數統計
incr:計數器、限速器
有序,可重復
常用命令:lpush、rpush、lpop、rpop、llen、lrange、lrem、lset
lpush+lpop:Stack(棧)
lpush+rpop:Queue(隊列)
lpush+ltrim:Capped Collection(有限集合)
lpush+brpop:Message Queue(消息隊列)
blpop:事件提醒(替代輪詢)
不支持數據類型的嵌套
適合存儲對象
常用命令:hset、hget、[hmset](http://doc.redisfans.com/hash/hmset ,.html)、hmget、hgetall、hexists、hincrby、hsetnx、hdel
無序、不重復
常用命令:sadd、srem、smembers、sdiff、sunion、sinter
sadd:標簽
sinter:交集
sunion:并集
有序、不重復
常用命令:zadd、zrange
zcount:統計信息
zrevrange:排行榜
常用命令:expire、ttl
常用命令:eval
首先,到redis官網找到要安裝的redis版本,Redis下載頁,我們這里選用v4.0.11
,依次執行下面命令:
# wget http://download.redis.io/releases/redis-4.0.11.tar.gz # tar xzf redis-4.0.11.tar.gz # cd redis-4.0.11 # make
到此安裝完成,然后可以通過make test
測試編譯狀態
# make test
無報錯完成編譯應該會有這樣的輸出:
報錯:需要tcl 8.5以上來運行redis test
You need tcl 8.5 or newer in order to run the Redis test make: *** [test] Error 1
下面安裝tcl8.6.1
:
# wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz # sudo tar xzvf tcl8.6.1-src.tar.gz # cd tcl8.6.1/unix/ # sudo ./configure # sudo make # sudo make install
再次運行make test
,沒問題之后,運行最后一步,完成安裝:
# make install
直接啟動:
# ./redis-server ../redis.conf
后臺啟動redis,只需修改redis.conf
配置文件的daemonize yes
,再次啟動即可。
# ./redis-server ../redis.conf
# ./redis-cli shutdown
# redis-cli
# redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> config get requirepass 1) "requirepass" 2) ""
127.0.0.1:6379> config set requirepass 123456 //密碼是123456 OK
建議key不要太長,不要超過1024字節,占用內存且會降低查詢效率
建議統一命名規則,例如:String:001:zhangsan:age
Bitmap 對于一些特定類型的計算非常有效。
假設現在我們希望記錄自己網站上的用戶的上線頻率,比如說,計算用戶 A 上線了多少天,用戶 B 上線了多少天,諸如此類,以此作為數據,從而決定讓哪些用戶參加 beta 測試等活動 —— 這個模式可以使用 SETBIT 和 BITCOUNT 來實現。
比如說,每當用戶在某一天上線的時候,我們就使用 SETBIT ,以用戶名作為 key
,將那天所代表的網站的上線日作為 offset
參數,并將這個 offset
上的為設置為 1
。
舉個例子,如果今天是網站上線的第 100 天,而用戶 peter 在今天閱覽過網站,那么執行命令 SETBIT peter 100 1
;如果明天 peter 也繼續閱覽網站,那么執行命令 SETBIT peter 101 1
,以此類推。
當要計算 peter 總共以來的上線次數時,就使用 BITCOUNT 命令:執行 BITCOUNT peter
,得出的結果就是 peter 上線的總天數。
更詳細的實現可以參考博文(墻外) Fast, easy, realtime metrics using Redis bitmaps 。
先更新庫數據,再刪除緩存
setnx
+lua
實現
public class RedisTool { private static final String LOCK_SUCCESS = "OK"; private static final String SET_IF_NOT_EXIST = "NX"; private static final String SET_WITH_EXPIRE_TIME = "PX"; private static final Long RELEASE_SUCCESS = 1L; // 獲取鎖 public static boolean getLock(Jedis jedis, String lockKey, String requestId, int expireTime) { String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime); if (LOCK_SUCCESS.equals(result)) { return true; } return false; } // 釋放鎖 public static boolean releaseLock(Jedis jedis, String lockKey, String requestId) { String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"; Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId)); if (RELEASE_SUCCESS.equals(result)) { return true; } return false; } }
到此,相信大家對“Redis的詳細介紹和應用”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。