Redis是一個key-value存儲系統。和Memcached相似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。與Memcached同樣,爲了保證效率,數據都是緩存在內存中。區別的是redis會週期性的把更新的數據寫入磁盤或者把修改操做寫入追加的記錄文件,而且在此基礎上實現了master-slave(主從)同步。html
Redis 是一個高性能的key-value數據庫。Redis的出現,很大程度補償了memcached這類key/value存儲的不足,在部分場合能夠對關係數據庫起到很好的補充做用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客戶端,使用很方便。[1] java
Redis支持主從同步。數據能夠從主服務器向任意數量的從服務器上同步,從服務器能夠是關聯其餘從服務器的主服務器。node
u 持久化:redis
l Redis能夠用來作緩存,也能夠作存儲;支持ADF和RDB兩種持久化方式數據庫
l Memcached只能緩存數據緩存
u 數據結構:服務器
l Redis有豐富的數據類型:字符串、鏈表,Hash、集合,有序集合數據結構
l Memcached通常就是字符串和對象架構
1.解壓:tar -zxvf redis-3.0.5.tar.gz併發
2.make
3.make PREFIX=/root/training/redis install
4.cp ~/tools/redis-3.0.5/redis.conf /root/training/redis/etc/
Redis的核心配置文件:redis.conf
Redis的命令腳本:
redis-benchmark 性能測試工具
redis-check-aof 檢查AOF日誌
redis-check-dump 檢查RDB日誌
redis-cli 啓動命令行客戶端
redis-sentinel
redis-server 啓動Redis服務
啓動Redis:
./redis-server ../etc/redis6379.conf
./redis-server ../etc/redis6380.conf
這樣就在6379和6380端口上,各自啓動了一個Redis實例;也能夠經過ps命令查看:
啓動Redis的客戶端:redis-cli
l 默認鏈接6739端口,也能夠經過-p指定鏈接的端口號:
l ./redis-cli --help顯式幫助信息
key操做
redis 的 key 是以 string 儲存的,redis 對於 key 經常使用的操做指令以下:
1.select db_name 使用指定數據庫 select 1 # 使用數據庫 1
2.exits key_name 檢查指定的 key 是否存在
3.get key_name 獲取指定 key 的 value
4.mget key1 [key2 ..] 獲取指定多個 key 的 value,
5.randomkey 隨機獲取一個 key
6.set key_name key_value 設置 key-value
7.getset key_name key_value 設置 key-value,並返回 key 的舊值
8.setnx key_name value 只有在 key 不存在時,才設置 key
9.mset key1 val1[ key1 val2...] 同時設置多個 key-value
10.del key_name 刪除指定的 key
11.rename key_name new_key_name 重命名指定key
12.type key_name 返回指定 key 的 value 的類型
13.dump key_name 序列化指定 key,並返回該 key 序列化後的 value
14.keys pattern 查找全部符合給定 pattern 的 key,支持使用 * 做爲通配符;
15.keys a* # 查找全部以 ‘a’ 開頭的 key
16.keys * # 查找全部 key
17.move key_name db_name 將指定 key-value 移動到指定數據庫
18.expire key_name seconds pexpire key_name milliseconds
給指定key設置過時時間,單位分別爲秒,毫秒
19.expireat key_name timestamp 設置指定的key 在指定的UNIX時間戳過時
20.ttl key_name pttl key_name
返回 key 的 TTL(Time to Live)生存時間,分別以 秒,毫秒爲單位;
21.persist key_name 移除指定 key 的過時時間,該 key 將持久保存
22.flushdb 刪除當前數據庫的全部 key
23.flushall 刪除全部數據庫的 key
其餘操做可進入連接查看
數據類型
① 字符串
② 鏈表
③ Hash
④ 無序集合
⑤ 有序集合
⑥ Redis數據類型案例分析:網站統計用戶登陸的次數
解決方案一:採用關係型數據庫
解決方案二:採用Redis存儲登陸信息
可使用Redis的setbit,登陸與否:有1和0就能夠表示
25.Java客戶端
① 基本操做
② 鏈接池
③ 使用Redis實現分佈式鎖
使用Maven搭建工程:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
1.Redis的事務
Redis對事務的支持目前還比較簡單。redis只能保證一個client發起的事務中的命令能夠連續的執行,而中間不會插入其餘client的命令。 因爲redis是單線程來處理全部client的請求的因此作到這點是很容易的。通常狀況下redis在接受到一個client發來的命令後會當即處理並 返回處理結果,可是當一個client在一個鏈接中發出multi命令有,這個鏈接會進入一個事務上下文,該鏈接後續的命令並非當即執行,而是先放到一個隊列中。當今後鏈接受到exec命令後,redis會順序的執行隊列中的全部命令。並將全部命令的運行結果打包到一塊兒返回給client.而後此鏈接就 結束事務上下文。
Oracle數據庫中的事務和Redis的事務對比
|
Oracle |
Redis |
開啓事務的方式 |
自動開啓事務 |
multi |
操做 |
DML語句 |
Redis命令 |
提交事務 |
commit |
exec |
回滾事務 |
rollback |
discard |
2.Redis的事務示例:銀行轉帳
從Tom轉100塊錢給Mike
3.Redis的鎖機制:watch
l 舉例:買票
4.Java應用程序中的事務和鎖
① 事務
② 鎖
5.Redis的消息機制:消息的發佈與訂閱,適合作在線聊天
publish:發佈消息
格式:publish channel名稱 「消息內容」
subscribe: 訂閱消息
格式:subscribe channel名稱
psubscribe: 使用通配符定義消息
格式:psubscribe channel*名稱
使用Java程序實現消息的發佈與訂閱,須要繼承JedisPubSub類
Redis 提供了多種不一樣級別的持久化方式:
一、RDB
工做原理:每隔必定時間給內存照一個快照,將內存中的數據寫入文件(rdb文件)配置參數:redis.conf文件(在conf文件中找到對應位置)
二、AOF:經過日誌的方式
例如:
set age 0
incr age
incr age
... 100次
最後 age的值是100
通過重寫後,直接執行: set age 100
2.能夠經過觀察aof日誌文件的大小
三、Redis持久化注意的問題
1.集羣的做用
l 主從備份 防止主機宕機
l 讀寫分離,分擔master的任務
l 任務分離,如從服分別分擔備份工做與計算工做
2.Redis 集羣的兩種部署方式
3.Redis主從服務的通訊原理
4.配置Redis的集羣(主從模式)
5.Redis集羣的高可用性
6.實現Redis的代理分片
./configure --prefix=/root/training/proxy
make
make install
Redis Cluster是Redis的分佈式解決方案,在Redis 3.0版本正式推出的,有效解決了Redis分佈式方面的需求。當遇到單機內存、併發、流量等瓶頸時,能夠採用Cluster架構達到負載均衡的目的。
咱們平常在對於redis的使用中,常常會遇到一些問題:
(1) 高可用問題,如何保證redis的持續高可用性。
(2) 容量問題,單實例redis內存沒法無限擴充,達到32G後就進入了64位世界,性能降低。
(3) 併發性能問題,redis號稱單實例10萬併發,但也是有盡頭的。
(1) 官方推薦,毋庸置疑。
(2) 去中心化,集羣最大可增長1000個節點,性能隨節點增長而線性擴展。
(3) 管理方便,後續可自行增長或摘除節點,移動分槽等等。
(4) 簡單,易上手。
分佈式數據庫首要解決把整個數據集按照分區規則映射到多個節點的問題,即把數據集劃分到多個節點上,每一個節點負責整個數據的一個子集。常見的分區規則有哈希分區和順序分區。Redis Cluster採用哈希分區規則。
虛擬槽分區巧妙地使用了哈希空間,使用分散度良好的哈希函數把全部的數據映射到一個固定範圍內的整數集合,整數定義爲槽(slot)。好比Redis Cluster槽的範圍是0 ~ 16383。槽是集羣內數據管理和遷移的基本單位。
Redis Cluster採用虛擬槽分區,全部的鍵根據哈希函數映射到0 ~ 16383,計算公式:slot = CRC16(key)&16383。每個節點負責維護一部分槽以及槽所映射的鍵值數據。
咱們以6個節點爲例,來介紹Redis Cluster的體系架構。其中:三個爲master節點,另外三個爲slave節點。
① Redis的編譯安裝
解壓:tar -zxvf redis-3.0.5.tar.gz
make
make PREFIX=/root/training/redis install
cp ~/tools/redis-3.0.5/redis.conf /root/training/redis/etc/
② 安裝Ruby環境和Ruby Redis接口
因爲建立和管理須要使用到redis-trib 工具,該工具位於 Redis 源碼的 src 文件夾中, 它是一個 Ruby 程序, 這個程序經過向實例發送特殊命令來完成建立新集羣,檢查集羣,或者對集羣進行從新分片(reshared)等工做,因此須要安裝Ruby環境和相應的Redis接口
下面是可使用yum來安裝Ruby:
[media]
name=Red Hat Enterprise Linux 7.4
baseurl=file:///cdroom
enabled=1
gpgcheck=1
gpgkey=file:///cdroom/RPM-GPG-KEY-redhat-release
③ 以6個節點爲例,安裝和部署Redis Cluster
daemonize yes
port 6379
cluster-enabled yes
cluster-config-file nodes/nodes-6379.conf
cluster-node-timeout 15000
dbfilename dump6379.rdb
appendonly yes
appendfilename "appendonly6379.aof"
redis6379.conf
redis6380.conf
redis6381.conf
redis6382.conf
redis6383.conf
redis6384.conf
④ 啓動Redis 實例
bin/redis-server conf/redis6379.conf
bin/redis-server conf/redis6380.conf
bin/redis-server conf/redis6381.conf
bin/redis-server conf/redis6382.conf
bin/redis-server conf/redis6383.conf
bin/redis-server conf/redis6384.conf
經過ps命令查看進程:
⑤ 使用redis-trib.rb自動部署方式
bin/redis-trib.rb create --replicas 1 192.168.56.72:6379 192.168.56.72:6380 192.168.56.72:6381 192.168.56.72:6382 192.168.56.72:6383 192.168.56.72:6384
注意:redis-trib.rb位於 Redis 源碼的 src 文件夾中,拷貝到bin目錄下。
其中:–replicas 1 表示咱們但願爲集羣中的每一個主節點建立一個從節點。
開始配置集羣:
⑥ 測試Redis Cluster
-c表示:登陸集羣
可使用:cluster nodes命令查看集羣中的節點
將源碼的utils/create-cluster目錄下,將create-cluster拷貝到安裝目錄的bin目錄下
修改create-cluster命令的路徑
import java.util.HashSet; import redis.clients.jedis.HostAndPort; import redis.clients.jedis.JedisCluster; public class TestRedisCluster { public static void main(String[] args) throws Exception { // 指定集羣的節點 HashSet<HostAndPort> nodes = new HashSet<>(); nodes.add(new HostAndPort("192.168.56.72", 6379)); nodes.add(new HostAndPort("192.168.56.72", 6380)); nodes.add(new HostAndPort("192.168.56.72", 6381)); nodes.add(new HostAndPort("192.168.56.72", 6382)); nodes.add(new HostAndPort("192.168.56.72", 6383)); nodes.add(new HostAndPort("192.168.56.72", 6384)); // 建立集羣 JedisCluster cluster = new JedisCluster(nodes); // 插入3*16383條數據 for (int i = 0; i < 3 * 16383; i++) { System.out.println("插入數據:" + i); cluster.set("mykey" + i, "myvalue:" + i); } // 關閉集羣客戶端 cluster.close(); System.out.println("完成"); } }
使用cluster <command> 命令來管理Redis Cluster:
命令 |
說明 |
info |
打印集羣的信息。 |
nodes |
列出集羣當前已知的全部節點(node)的相關信息。 |
meet <ip> <port> |
將ip和port所指定的節點添加到集羣當中。 |
addslots <slot> [slot ...] |
將一個或多個槽(slot)指派(assign)給當前節點。 |
delslots <slot> [slot ...] |
移除一個或多個槽對當前節點的指派。 |
slots |
列出槽位、節點信息。 |
slaves <node_id> |
列出指定節點下面的從節點信息。 |
replicate <node_id> |
將當前節點設置爲指定節點的從節點。 |
saveconfig |
手動執行命令保存保存集羣的配置文件,集羣默認在配置修改的時候會自動保存配置文件。 |
keyslot <key> |
列出key被放置在哪一個槽上。 |
flushslots |
移除指派給當前節點的全部槽,讓當前節點變成一個沒有指派任何槽的節點。 |
countkeysinslot <slot> |
返回槽目前包含的鍵值對數量。 |
getkeysinslot <slot> <count> |
返回count個槽中的鍵。 |
setslot <slot> node <node_id> |
將槽指派給指定的節點,若是槽已經指派給另外一個節點,那麼先讓另外一個節點刪除該槽,而後再進行指派。 |
setslot <slot> migrating <node_id> |
將本節點的槽遷移到指定的節點中。 |
setslot <slot> importing <node_id> |
從 node_id 指定的節點中導入槽 slot 到本節點。 |
setslot <slot> stable |
取消對槽 slot 的導入(import)或者遷移(migrate) |
failover |
手動進行故障轉移。 |
forget <node_id> |
從集羣中移除指定的節點,這樣就沒法完成握手,過時時爲60s,60s後兩節點又會繼續完成握手。 |
reset [HARD|SOFT] |
重置集羣信息,soft是清空其餘節點的信息,但不修改本身的id,hard還會修改本身的id,不傳該參數則使用soft方式。 |
count-failure-reports <node_id> |
列出某個節點的故障報告的長度。 |
SET-CONFIG-EPOCH |
設置節點epoch,只有在節點加入集羣前才能設置。 |
命令詳解:cluster info
命令詳解:cluster nodes(可使用excel 導入命令輸出,方便查看)
幾點說明:
命令詳解:cluster slots
其餘幾個命令:
① 增長新的配置文件:redis6385.conf 和 redis6386.conf
② 按照以前的配置修改對應參數
③ 啓動新的節點
bin/redis-server conf/redis6385.conf
bin/redis-server conf/redis6386.conf
④ 添加主節點
bin/redis-trib.rb add-node 192.168.56.72:6385 192.168.56.72:6379
其中:
192.168.56.72:6385是新添加的節點
192.168.56.72:6379是集羣中,任一個舊節點
⑤ 檢查集羣的節點信息
bin/redis-trib.rb check 192.168.56.72:6379
⑥ 添加從節點
bin/redis-trib.rb add-node --slave --master-id f27013eaebcf998078edf1621e4433534f8d8b11 192.168.56.72:6386 192.168.56.72:6379
其中:
--slave:表示添加的是一個從節點
--master-id:表示該從節點的主節點
192.168.56.72:6386:新添加的從節點
192.168.56.72:6379:是集羣中,任一個舊節點
⑦ 從新檢查集羣的狀態信息
bin/redis-trib.rb check 192.168.56.72:6379
⑧ 從新分配slot
bin/redis-trib.rb reshard 192.168.56.72:6379
⑨ 從新查看集羣的節點槽的信息,能夠看到新添加的節點信息。
cluster slots
或者使用:
bin/redis-trib.rb check 192.168.56.72:6379
刪除節點
① 先刪除從節點:
bin/redis-trib.rb del-node 192.168.56.72:6385 21e3e82610ce206708aa8f4189e2c9b2f3d1c540
② 再刪除主節點
bin/redis-trib.rb del-node 192.168.56.72:6386 f757ce35102b3aaff3621b539e2dc675eafe3c01
③ 若是出現如下錯誤,須要先清空(移動)該節點上的slot,再刪除
第一步:bin/redis-trib.rb reshard 192.168.56.72:6386
第二步:bin/redis-trib.rb del-node 192.168.56.72:6386 f757ce35102b3aaff3621b539e2dc675eafe3c01
④ 從新檢查集羣的信息,發生節點已經被刪除
bin/redis-trib.rb check 192.168.56.72:6379
① 首先,爲了看到演示的效果,清除一下以前的設置,仍是以六個節點爲例
② 啓動每一個節點,並建立集羣
bin/redis-server conf/redis6379.conf
bin/redis-server conf/redis6380.conf
bin/redis-server conf/redis6381.conf
bin/redis-server conf/redis6382.conf
bin/redis-server conf/redis6383.conf
bin/redis-server conf/redis6384.conf
bin/redis-trib.rb create --replicas 1 192.168.56.72:6379 192.168.56.72:6380 192.168.56.72:6381 192.168.56.72:6382 192.168.56.72:6383 192.168.56.72:6384
③ 檢查集羣狀態
bin/redis-trib.rb check 192.168.56.72:6379
④ 殺掉6379上的主節點,並從新檢查集羣的狀態
⑤ 稍等一段時間,從新檢查集羣的狀態
⑥ 若是從新啓動6379上的實例,它將變成6382的從節點