學會與人相處,建立良好的人際關係,
這是在職場中獲得成功的關鍵。
Redis是一種記憶體資料庫,它將資料儲存在記憶體中,因此它非常快速。但是,如果Redis程序意外終止,所有資料將丟失。為了解決這個問題,Redis提供了持久化功能,它可以將記憶體中的資料非同步寫入磁碟,以便在Redis重啟後可以恢復資料。
RDB持久化是將Redis在某個時間點上的資料儲存到硬碟上,可以看作是對Redis記憶體中的資料做一個快照。RDB持久化可以通過設定Redis伺服器的時間間隔來自動觸發,也可以手動執行。
AOF持久化是將Redis的寫操作以文字形式追加到檔案中。AOF檔案中的每個寫操作都是一個Redis命令,當Redis伺服器重啟時,可以通過執行AOF檔案中的所有命令來恢復資料。
RDB持久化的組態檔為redis.conf。在組態檔中,可以通過以下設定項來控制RDB持久化的行為:
AOF持久化的組態檔為redis.conf。在組態檔中,可以通過以下設定項來控制AOF持久化的行為:
RDB持久化的恢復比較簡單,只需將RDB檔案複製到Redis伺服器的工作目錄,並在redis.conf檔案中指定RDB檔案的路徑即可。Redis伺服器啟動時會自動載入RDB檔案,並恢復資料。
人生如一場旅程,不要只看到目的地,
更要享受旅途中的美好。
AOF持久化的恢復相對複雜。首先,需要將AOF檔案載入到Redis伺服器中:
plaintextCopy code
redis-cli
CONFIG SET appendonly yes
BGREWRITEAOF
然後,需要清空Redis伺服器中的資料:
plaintextCopy code
redis-cli
FLUSHALL
最後,執行AOF檔案中的所有命令,恢復資料:
plaintextCopy code
redis-cli
CONFIG SET appendonly yes
BGREWRITEAOF
在選擇持久化方式時,需要根據實際的業務場景和需求來選擇RDB或AOF持久化。如果對資料完整性要求較高,可以選擇AOF持久化;如果對資料完整性要求不高,可以選擇RDB持久化。
持久化會對Redis伺服器的效能產生一定的影響,特別是在執行RDB持久化時,由於需要fork出子程序,會佔用一定的CPU和記憶體資源。因此,在設定持久化時,需要根據實際情況來平衡資料安全和效能的需求。
由於Redis的持久化是非同步的,因此在Redis意外終止時,可能會丟失部分資料。為了最小化資料丟失的風險,可以使用AOF持久化,並將appendfsync設定為always。這將確保每個寫操作都同步到磁碟上的AOF檔案中。
Redis事務是指在一次操作中執行多個命令,並且這些命令要麼全部被執行,要麼全部不執行。Redis事務可以保證一系列命令的原子性執行。
職場中最重要的能力並不是技術或知識,
而是溝通和共同作業的能力。
範例:
/**
* 事務操作
* @param isOpenError 是否開啟異常
*/
public void transactionalMethod(boolean isOpenError) {
redisTemplate.execute(new SessionCallback<List<Object>>() {
@Override
public List<Object> execute(RedisOperations operations) {
operations.multi(); // 開啟事務
ValueOperations<String, String> valueOps = operations.opsForValue();
valueOps.set("key1", "value1");
if(isOpenError){
int i = 1 / 0;
}
valueOps.set("key2", "value2");
List exec = operations.exec();//提交事務
return exec;
}
});
}
釋出和訂閱是 Redis 的一種訊息傳遞機制,它可以實現多個使用者端之間的訊息通訊。下面是一個簡單的 Redis 釋出和訂閱的範例
實現訊息訂閱者
public class RedisMessageListener implements MessageListener {
@Override
public void onMessage(Message message, byte[] bytes) {
System.out.println("收到訊息: " + message.toString());
}
}
註冊訊息訂閱者
@Bean
public RedisMessageListenerContainer redisContainer() {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(redisTemplate().getConnectionFactory());
container.addMessageListener(new RedisMessageListener(), new ChannelTopic("pubsub:example"));
return container;
}
傳送訊息
public void publish(String message) {
redisTemplate.convertAndSend("pubsub:example", message);
}
永遠保持謙虛和學習的心態,
才能不斷提升自己,贏得更多的機會和尊重。
Redis 支援 Lua 指令碼,可以通過編寫 Lua 指令碼來實現複雜的資料操作和處理。Redis 的 Lua 指令碼可以存取 Redis 資料庫,Redis 提供的各種命令和函數。
下面是一個使用lua指令碼實現redis自增計數器的範例
public Long increment(String key) {
DefaultRedisScript<Long> script = new DefaultRedisScript<>();
script.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua/increment.lua")));
script.setResultType(Long.class);
List<String> keys = Collections.singletonList(key);
return redisTemplate.execute(script, keys);
}
lua指令碼
local key = KEYS[1]
local value = redis.call('INCR', key)
return value
使用 Lua 指令碼可以將多個 Redis 命令封裝在一個指令碼中,減少網路開銷和伺服器負載。此外,Lua 指令碼還可以實現 Redis 不支援的資料結構和演演算法,可以擴充套件 Redis 的功能和應用範圍。
管道(pipeline)是一種高效的Redis命令執行方式,它可以在一次通訊中傳送多個Redis命令,並一次性獲取所有命令的響應結果。這種方式可以有效地降低Redis伺服器的網路延遲和通訊開銷,提高Redis的效能。
下面是一個使用管道操作的範例
/**
* 管道操作
* 注意管道操作不支援事務和watch命令,需要謹慎使用。
* 管道操作會將多個命令打包成一個請求傳送給Redis伺服器,
* 如果其中一個命令執行失敗,那麼整個管道操作都會失敗
*/
public void pipelineExample() {
List<Object> results = redisTemplate.executePipelined(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
connection.stringCommands().set("key1".getBytes(), "value1".getBytes());
connection.stringCommands().set("key2".getBytes(), "value2".getBytes());
connection.stringCommands().set("key3".getBytes(), "value3".getBytes());
return null;
}
});
System.out.println(results); // 列印結果
}
https://gitee.com/youlaiorg/youlai-learning.git
本文介紹了Redis的高階特性,包括持久化、事務、釋出訂閱、lua指令碼和管道操作。其中,持久化可以實現資料的持久化儲存,事務可以保證一系列命令的原子性執行,釋出訂閱可以實現多個使用者端之間的訊息通訊,lua指令碼可以實現複雜的資料操作和處理,管道操作可以在一次通訊中傳送多個Redis命令。此外,本文還介紹了Redis高效能、高可用、高可延伸性的原理,包括基於記憶體的資料結構、單執行緒的模型、高效的網路通訊、非同步非阻塞式IO和高效的持久化機制。
做事要講求團隊合作,相互支援,共同進步。