Redis事務、持久化、主從複製、哨兵、JRedis和JRedis Pool(摘抄)
事務是指一系列操作步驟,這一系列的操作步驟,要麼完全執行,要麼完全地不執行
Redis中的事務是一組命令的集合,至少是兩個或兩個以上的命令,redis事務保證這些命令被執行時中間不會被任何操作打斷
(1)multi標記一個事務的開始,事務內的多條命令會按照先後順序被放入一個佇列中,返回值總是ok
(2)exec執行所有事務內的命令,返回事務內的所有執行語句內容,事務被打斷返回nil,如果其中一條事務語法錯誤,則無法執行事務(任意一條),會完全放棄該事務內的任意命令。
另一個錯誤是語法沒有錯誤,但執行出錯,不報錯的事務會執行成功,執行錯誤的命令報錯(因為沒有回滾機制)
(3)discard取消事務,放棄執行事務塊的所有命令,返回值綜述ok
(4)watch監視該值的改變
redis的watch機制:使用watch監視一個或多個key,跟蹤key的value修改情況,如果有key的value值在事務Exec執行之前被修改了,整個事務被取消。Exec返回提示資訊,表示事務已經失敗。
監視後,發現age的值已經被改動,所以放棄當前的事務。注意,redis同一時間只操作一個key
這事實上就是樂觀鎖的實現機制
(4)持久化,即儲存將資料儲存到一個不會丟失的地方,如果把資料放到記憶體中,非常容易丟失,所以放在記憶體中的資料不是持久化,而放到磁碟就算一種持久化,Redis提供兩種機制對資料進行持久化儲存,便於發生故障後能迅速回複數據(AOF和RDB)
=================================
Redis Database(RDB)指定的時間間隔將記憶體中的資料寫到磁碟,資料恢復時將快照檔案讀到記憶體中。
RDB儲存了某個時間點的全部資料集,儲存在一個二進位制檔案中,只有一個檔案,預設是dump.rdb。RDB技術非常適合做備份,可以儲存最近一個小時,一天,一個月的全部資料。儲存資料是在單獨的程序中寫檔案,不影響redis的正常使用。RDB回覆資料時比其它AOP速度更快
RDB方式的資料持久化,僅需在redis.conf檔案中配置即可,預設配置是啟用的。在配置檔案redis.conf中搜索SNAPSHOTTING,查詢在註釋開始和結束之間的關於RDB的配置說明。配SNAPSHOTTING地方有三處。
①配置執行RDB生成快照檔案的時間策略,對Redis進行設定,讓它在“N秒內資料集至少有M個key改動”這一條件被滿足時,自動儲存一次資料集。
配置格式:save seconds change
save 900 1
save 300 10
save 60 100000
這三個策略是可以同時觸發的
②dbfilename:設定RDB的檔名,預設檔名為dump.rdb
③dir:指定RDB檔案的儲存位置,預設是當前目錄
RDB的缺點就是,其會丟失資料,一旦沒有滿足觸發策略容易發生資料丟失
=================================
Append-only File(AOF),Redis每次接收到一條改變資料的命令時,它將把該命令寫到一個AOF檔案中(只記錄命令,是一個文字檔案,可以修改),當Redis重新啟動時,它通過執行AOF檔案中的所有命令來恢復資料。
AOF方式的資料持久化,在redis.conf檔案中配置即可:
①appendonly:預設是no,改成yes,即開啟aof持久化
②appendfilename:指定AOF檔名,預設檔名為appendonly.aof
③dir:指定RDB和AOF檔案存放的目錄,預設是
④appendfsync:配置向aof檔案寫命令資料的策略:
no:不主動進行同步操作,而是完全交給作業系統來做(即每30秒一次),比較快但不是很安全
always:每次執行寫入都會執行同步,慢但是安全
everysec:每秒執行一次同步操作,慢一些但是比較安全
⑤auto-aof-rewrite-min-size:允許重寫的最小AOF檔案大小,預設是64M。當aof檔案大於64M時,開始整理aof檔案,去掉無用的操作命令,縮小aof檔案。
(5)redis伺服器的主從複製
為了避免單點故障,我們需要將資料複製多份部署在多臺不同的伺服器上,即使有一臺伺服器出現故障,其他伺服器依然可以繼續提供服務。
這就要求當一臺伺服器上的資料更新後,自動將更新的資料同步到其它伺服器上,那該怎麼實現?Redis主從複製
主master負責資料的修改操作,從redis全部負責資料的讀操作。讀寫分離可以降低伺服器壓力。
通過啟動多個redis-server可以模擬主從複製結構。
Redis主從複製實現(master/salve)
方式1:修改配置檔案,啟動時,伺服器讀取配置檔案,並自動稱為指定伺服器的從伺服器,從而構成主從複製關係
新建三個redis的配置檔案
如果redis啟動,先停止
作為Master的redis埠是6380
作為Slaver的redis埠分別是6382,6384
從原有的redis.conf拷貝三份,分別命名為redis6380.conf,redis6382.conf,redis6384.conf。
複製這幾個就是為了在一臺機子上啟動多個redis server
編輯Master配置檔案
redis6380.conf在空檔案中加入如下內容:
include /usr/local/redis-3.2.9/redis.conf
包含原來的配置檔案的內容,將redis.conf加入到當前配置檔案
daemonize yes
表示redis是後臺啟動
port 6380
當前redis的埠號
pidfile /var/run/redis_6380.pid
linux執行程式的唯一標識,需要一個位置儲存唯一的表示路徑
logfile 6380.log
設定日誌檔案位置
dbfilename dump6380.rdb
rdb儲存的位置
編輯Slave配置檔案
redis6382.conf和redis6384.conf在空檔案中加入如下內容:
include /usr/local/redis-3.2.9/redis.conf
daemonize yes
port 6382
pidfile /var/run/redis_6382.pid
logfile 6382.log
dbfilename dump6382.rdb
slaveof 127.0.0.1 6380
設定主master地址
===================================
./redis-cli -p 6380
Master伺服器的客戶端
info replication
顯示伺服器的關係資訊
同樣,連線到6382,顯示的是up
在主伺服器上新增key和val,主從都會顯示。從伺服器只能讀不能寫。
當Master服務出現故障,需要手動將slave中的一個提升為master,剩下的slave掛至新的master上
命令:
①:slaveof no one
將一臺slave伺服器提升為Master
②:slaveof 127.0.0.1 6381
方式二:./redis-server --slaveof master-ip master-port在啟動redis時指定當前服務成為某個主redis服務的從Slave
(6)哨兵系統
可自動化的處理故障
- 監控:Sentinel不斷的檢查主服務和從服務是否按照預期正常工作
- 提醒:被監控的redis出現問題時,Sentinel會通知管理員或其它應用程式
- 自動故障轉移:監控的主redis不能正常工作,Sentinel會開始進行故障遷移操作。就是將從伺服器提升為主伺服器,其它伺服器掛到新主伺服器之上。
- 每個哨兵(Sentinel)獨立執行,可以進行通訊,並交換監控的結果。哨兵通過心跳機制來檢查主從伺服器是否正常。哨兵的個數必須是奇數,從而投票覺得當前主伺服器是否執行正常。
安裝完redis,哨兵就已經存在,redis-sentinel。我們在一臺機子上模擬三個哨兵系統,複製三份sentinel.conf檔案:
Sentinel系統預設port是26379。三個配置port分別設定為26380,26382,26384。三個檔案分別命名:
- sentinel26380.conf
- sentinel26382.conf
- sentinel26384.conf
三個sentinel配置檔案修改:
1、修改port 26380 port 26382 port 26384
2、修改sentinel monitor mymaster 127.0.0.1 6380 2
格式:sentinel monitor name masterIp masterPort Quorum投票數
修改之後執行哨兵系統
一旦主redis關閉,會自動轉化主redis
此外,如果新啟動了一個伺服器並且配置哨兵,會自動新增到從伺服器之中
(7)安全設定
訪問redis預設是沒有密碼的。要設定redis訪問密碼,修改redis.conf中requirepass 密碼。因為redis速度很快,所以在一臺比較好的 伺服器下,一個外部使用者可以1s進行150k次密碼嘗試,需要指定非常非常強大的密碼來防止暴力破解。
開啟訪問密碼設定
修改redis.conf,找到requirepass
只要改了配置檔案就重新載入
兩種密碼的使用方式:
其次,redis可以繫結ip,修改redis.conf檔案,把#bind 127.0.0.1前面的註釋#號去掉,然後把127.0.0.1改成允許訪問你的redis伺服器的ip地址,表示只允許該ip進行訪問。多個ip使用空格分隔
最後,修改redis的埠是很重要的,使用預設埠非常危險,redis.conf中修改port6379,將其修改為自己指定的埠,埠1024以內是保留給作業系統,使用者可以使用1024-65535
(8)Jedis操作Redis
Jedis有執行緒不安全的問題,一般跟commons-pool(執行緒池)一起使用。
package com.fty;
import redis.clients.jedis.Jedis;
import java.util.List;
public class RedisString {
public static void main(String[] args) {
/**
* 1、修改redis.conf,啟動redis需要指定redis.conf的位置
* 2、關閉linux防火牆,或者讓redis的埠號通過防火牆 systemctl statsu firewalld
*/
//建立Jredis物件,指定連線的redis伺服器的ip埠
Jedis jedis = new Jedis("127.0.0.1", 6379);
// jedis.auth("密碼");
//呼叫Jedis物件的方法操作Redis資料
jedis.set("break", "豆漿和油條");
//獲取key的值
String value = jedis.get("break");
System.out.println(value);
//mset一次建立多個key-value
jedis.mset("lunch","紅燒肉蓋飯", "dinner", "牛排");
//獲取多個key對應的值mget
List<String> values = jedis.mget("break", "lunch", "dinner");
for(String val : values) {
System.out.println(val);
}
}
}
使用Jedis Pool
package com.fty;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class RedisUtils {
private static JedisPool pool;
//建立JedisPool物件
public static JedisPool open(String ip, int port) {
if(pool == null) {
//建立JedisPool
//建立JedisPoolConfig,給config設定連線池的引數,使用config物件去建立JedisPool
JedisPoolConfig config = new JedisPoolConfig();
//給config設定連線池的引數
config.setMaxTotal(10);//設定最大的執行緒數,一個執行緒就是一個Jedis物件
config.setMaxIdle(2);//設定最大空閒數
config.setTestOnBorrow(true);//設定檢查項為true,標識執行緒池中獲取的物件一定是經過檢查可用的
/**
* poolConfig 配置器
* host:redis所在的ip
* port:redis的埠
* timeout:連線redis的超時事件
* password:redis訪問密碼
*/
pool = new JedisPool(config, "localhost", 6379, 6000, "密碼");//建立Pool物件
}
return pool;
}
//關閉pool物件
public static void close() {
if(pool != null) {
pool.close();
}
}
public static void main(String[] args) {
//從JedisPool中獲取JedisPool物件
JedisPool pool = null;
Jedis jedis = null;
try {
pool = open("localhost", 6379);
jedis = pool.getResource();
/**
* 拿到Jedis後就能進行set 和 get
*/
} catch (Exception e) {
e.printStackTrace();
} finally {
//關閉Jedis物件,從Pool中獲取的Jedis放回到Pool,共其它請求使用
if(jedis != null) {
jedis.close();//放回池中
}
}
}
}