当前位置:网站首页>redisson使用全解——redisson官方文檔+注釋(上篇)
redisson使用全解——redisson官方文檔+注釋(上篇)
2022-07-01 07:17:00 【禿了也弱了。】
文章目錄
- 官方文檔
- Redisson項目介紹
- 一、概述
- 二、配置方法
- 三、程序接口調用方式
- 四、數據序列化
- 五、單個集合數據分片(Sharding)
- 六、分布式對象
- 七、分布式集合
- 7.1. 映射(Map)
- 7.2. 多值映射(Multimap)
- 7.3. 集(Set)
- 7.4. 有序集(SortedSet)
- 7.5. 計分排序集(ScoredSortedSet)
- 7.6. 字典排序集(LexSortedSet)
- 7.7. 列錶(List)
- 7.8. 隊列(Queue)
- 7.9. 雙端隊列(Deque)
- 7.10. 阻塞隊列(Blocking Queue)
- 7.11. 有界阻塞隊列(Bounded Blocking Queue)
- 7.12. 阻塞雙端隊列(Blocking Deque)
- 7.13. 阻塞公平隊列(Blocking Fair Queue)
- 7.14. 阻塞公平雙端隊列(Blocking Fair Deque)
- 7.15. 延遲隊列(Delayed Queue)
- 7.16. 優先隊列(Priority Queue)
- 7.17. 優先雙端隊列(Priority Deque)
- 7.18. 優先阻塞隊列(Priority Blocking Queue)
- 7.19. 優先阻塞雙端隊列(Priority Blocking Deque)
redisson使用全解——redisson官方文檔+注釋(上篇)
redisson使用全解——redisson官方文檔+注釋(中篇)
redisson使用全解——redisson官方文檔+注釋(下篇)
官方文檔
Redisson項目介紹
Redisson是架設在Redis基礎上的一個Java駐內存數據網格(In-Memory Data Grid)。充分的利用了Redis鍵值數據庫提供的一系列優勢,基於Java實用工具包中常用接口,為使用者提供了一系列具有分布式特性的常用工具類。使得原本作為協調單機多線程並發程序的工具包獲得了協調分布式多機多線程並發系統的能力,大大降低了設計和研發大規模分布式系統的難度。同時結合各富特色的分布式服務,更進一步簡化了分布式環境中程序相互之間的協作。
Redisson采用了基於NIO的Netty框架,不僅能作為Redis底層驅動客戶端,具備提供對Redis各種組態形式的連接功能,對Redis命令能以同步發送、异步形式發送、异步流形式發送或管道形式發送的功能,LUA脚本執行處理,以及處理返回結果的功能,還在此基礎上融入了更高級的應用方案,不但將原生的Redis Hash,List,Set,String,Geo,HyperLogLog等數據結構封裝為Java裏大家最熟悉的映射(Map),列錶(List),集(Set),通用對象桶(Object Bucket),地理空間對象桶(Geospatial Bucket),基數估計算法(HyperLogLog)等結構,在這基礎上還提供了分布式的多值映射(Multimap),本地緩存映射(LocalCachedMap),有序集(SortedSet),計分排序集(ScoredSortedSet),字典排序集(LexSortedSet),列隊(Queue),阻塞隊列(Blocking Queue),有界阻塞列隊(Bounded Blocking Queue),雙端隊列(Deque),阻塞雙端列隊(Blocking Deque),阻塞公平列隊(Blocking Fair Queue),延遲列隊(Delayed Queue),布隆過濾器(Bloom Filter),原子整長形(AtomicLong),原子雙精度浮點數(AtomicDouble),BitSet等Redis原本沒有的分布式數據結構。不僅如此,Redisson還實現了Redis文檔中提到像分布式鎖Lock這樣的更高階應用場景。事實上Redisson並沒有不止步於此,在分布式鎖的基礎上還提供了聯鎖(MultiLock),讀寫鎖(ReadWriteLock),公平鎖(Fair Lock),紅鎖(RedLock),信號量(Semaphore),可過期性信號量(PermitExpirableSemaphore)和閉鎖(CountDownLatch)這些實際當中對多線程高並發應用至關重要的基本部件。正是通過實現基於Redis的高階應用方案,使Redisson成為構建分布式系統的重要工具。
在提供這些工具的過程當中,Redisson廣泛的使用了承載於Redis訂閱發布功能之上的分布式話題(Topic)功能。使得即便是在複雜的分布式環境下,Redisson的各個實例仍然具有能够保持相互溝通的能力。在以這為前提下,結合了自身獨有的功能完善的分布式工具,Redisson進而提供了像分布式遠程服務(Remote Service),分布式執行服務(Executor Service)和分布式調度任務服務(Scheduler Service)這樣適用於不同場景的分布式服務。使得Redisson成為了一個基於Redis的Java中間件(Middleware)。
Redisson Node的出現作為駐內存數據網格的重要特性之一,使Redisson能够獨立作為一個任務處理節點,以系統服務的方式運行並自動加入Redisson集群,具備集群節點彈性增减的能力。然而在真正意義上讓Redisson發展成為一個完整的駐內存數據網格的,還是具有將基本上任何複雜、多維結構的對象都能變為分布式對象的分布式實時對象服務(Live Object Service),以及與之相結合的,在分布式環境中支持跨節點對象引用(Distributed Object Reference)的功能。這些特色功能使Redisson具備了在分布式環境中,為Java程序提供了堆外空間(Off-Heap Memory)儲存對象的能力。
Redisson提供了使用Redis的最簡單和最便捷的方法。Redisson的宗旨是促進使用者對Redis的關注分離(Separation of Concern),從而讓使用者能够將精力更集中地放在處理業務邏輯上。如果您現在正在使用其他的Redis的Java客戶端,希望Redis命令和Redisson對象匹配列錶 能够幫助您輕松的將現有代碼遷徙到Redisson裏來。如果目前Redis的應用場景還僅限於作為緩存使用,您也可以將Redisson輕松的整合到像Spring和Hibernate這樣的常用框架裏。除此外您也可以間接的通過Java緩存標准規範JCache API (JSR-107)接口來使用Redisson。
Redisson生而具有的高性能,分布式特性和豐富的結構等特點恰巧與Tomcat這類服務程序對會話管理器(Session Manager)的要求相吻合。利用這樣的特點,Redisson專門為Tomcat提供了會話管理器(Tomcat Session Manager)。
在此不難看出,Redisson同其他Redis Java客戶端有著很大的區別,相比之下其他客戶端提供的功能還僅僅停留在作為數據庫驅動層面上,比如僅針對Redis提供連接方式,發送命令和處理返回結果等。像上面這些高層次的應用則只能依靠使用者自行實現。
Redisson支持Redis 2.8以上版本,支持Java1.6+以上版本。
一、概述
Redisson是一個在Redis的基礎上實現的Java駐內存數據網格(In-Memory Data Grid)。它不僅提供了一系列的分布式的Java常用對象,還提供了許多分布式服務。其中包括(BitSet, Set, Multimap, SortedSet, Map, List, Queue, BlockingQueue, Deque, BlockingDeque, Semaphore, Lock, AtomicLong, CountDownLatch, Publish / Subscribe, Bloom filter, Remote service, Spring cache, Executor service, Live Object service, Scheduler service) Redisson提供了使用Redis的最簡單和最便捷的方法。Redisson的宗旨是促進使用者對Redis的關注分離(Separation of Concern),從而讓使用者能够將精力更集中地放在處理業務邏輯上。
關於Redisson項目的詳細介紹可以在官方網站找到。
每個Redis服務實例都能管理多達1TB的內存。
能够完美的在雲計算環境裏使用,並且支持AWS ElastiCache主備版,AWS ElastiCache集群版,Azure Redis Cache和阿裏雲(Aliyun)的雲數據庫Redis版
以下是Redisson的結構:
Redisson作為獨立節點 可以用於獨立執行其他節點發布到分布式執行服務 和 分布式調度任務服務 裏的遠程任務。
如果你現在正在使用其他的Redis的Java客戶端,那麼Redis命令和Redisson對象匹配列錶 能够幫助你輕松的將現有代碼遷徙到Redisson框架裏來。
Redisson底層采用的是Netty 框架。支持Redis 2.8以上版本,支持Java1.6+以上版本。
歡迎試用高性能Redisson PRO版。
二、配置方法
引入pom:
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.12.3</version>
</dependency>
2.1. 程序化配置方法
Redisson程序化的配置方法是通過構建Config對象實例來實現的。例如:
Config config = new Config();
config.setTransportMode(TransportMode.EPOLL); // 默認是NIO的方式
config.useClusterServers()
//可以用"rediss://"來啟用SSL連接,前綴必須是redis:// or rediss://
.addNodeAddress("redis://127.0.0.1:7181");
2.2. 文件方式配置
Redisson既可以通過用戶提供的YAML格式的文本文件來配置
2.2.1 通過YAML格式配置
Redisson的配置文件可以是或YAML格式。 也通過調用config.fromYAML方法並指定一個File實例來實現讀取YAML格式的配置:
Config config = Config.fromYAML(new File("config-file.yaml"));
RedissonClient redisson = Redisson.create(config);
調用config.toYAML方法可以將一個Config配置實例序列化為一個含有YAML數據類型的字符串:
Config config = new Config();
// ... 省略許多其他的設置
String jsonFormat = config.toYAML();
2.3. 常用設置
以下是關於org.redisson.Config類的配置參數,它適用於所有Redis組態模式(單機,集群和哨兵)
codec(編碼)
默認值: org.redisson.codec.JsonJacksonCodec
Redisson的對象編碼類是用於將對象進行序列化和反序列化,以實現對該對象在Redis裏的讀取和存儲。Redisson提供了以下幾種的對象編碼應用,以供大家選擇:
編碼類名稱 | 說明 |
---|---|
org.redisson.codec.JsonJacksonCodec | Jackson JSON 編碼 默認編碼 |
org.redisson.codec.AvroJacksonCodec | Avro 一個二進制的JSON編碼 |
org.redisson.codec.SmileJacksonCodec | Smile 另一個二進制的JSON編碼 |
org.redisson.codec.CborJacksonCodec | CBOR 又一個二進制的JSON編碼 |
org.redisson.codec.MsgPackJacksonCodec | MsgPack 再來一個二進制的JSON編碼 |
org.redisson.codec.IonJacksonCodec | Amazon Ion 亞馬遜的Ion編碼,格式與JSON類似 |
org.redisson.codec.KryoCodec | Kryo 二進制對象序列化編碼 |
org.redisson.codec.SerializationCodec | JDK序列化編碼 |
org.redisson.codec.FstCodec | FST 10倍於JDK序列化性能而且100%兼容的編碼 |
org.redisson.codec.LZ4Codec | LZ4 壓縮型序列化對象編碼 |
org.redisson.codec.SnappyCodec | Snappy 另一個壓縮型序列化對象編碼 |
org.redisson.client.codec.JsonJacksonMapCodec | 基於Jackson的映射類使用的編碼。可用於避免序列化類的信息,以及用於解决使用byte[]遇到的問題。 |
org.redisson.client.codec.StringCodec | 純字符串編碼(無轉換) |
org.redisson.client.codec.LongCodec | 純整長型數字編碼(無轉換) |
org.redisson.client.codec.ByteArrayCodec | 字節數組編碼 |
org.redisson.codec.CompositeCodec | 用來組合多種不同編碼在一起 |
threads(線程池數量)
默認值: 當前處理核數量 * 2
這個線程池數量被所有RTopic對象監聽器,RRemoteService調用者和RExecutorService任務共同共享。
nettyThreads (Netty線程池數量)
默認值: 當前處理核數量 * 2
這個線程池數量是在一個Redisson實例內,被其創建的所有分布式數據類型和服務,以及底層客戶端所一同共享的線程池裏保存的線程數量。
executor(線程池)
單獨提供一個用來執行所有RTopic對象監聽器,RRemoteService調用者和RExecutorService任務的線程池(ExecutorService)實例。
eventLoopGroup
用於特別指定一個EventLoopGroup. EventLoopGroup是用來處理所有通過Netty與Redis服務之間的連接發送和接受的消息。每一個Redisson都會在默認情况下自己創建管理一個EventLoopGroup實例。因此,如果在同一個JVM裏面可能存在多個Redisson實例的情况下,采取這個配置實現多個Redisson實例共享一個EventLoopGroup的目的。
只有io.netty.channel.epoll.EpollEventLoopGroup或io.netty.channel.nio.NioEventLoopGroup才是允許的類型。
transportMode(傳輸模式)
默認值:TransportMode.NIO
可選參數:
TransportMode.NIO,
TransportMode.EPOLL - 需要依賴裏有netty-transport-native-epoll包(Linux)
TransportMode.KQUEUE - 需要依賴裏有 netty-transport-native-kqueue包(macOS)
lockWatchdogTimeout(監控鎖的看門狗超時,單比特:毫秒)
默認值:30000
監控鎖的看門狗超時時間單比特為毫秒。該參數只適用於分布式鎖的加鎖請求中未明確使用leaseTimeout參數的情况。如果該看門口未使用lockWatchdogTimeout去重新調整一個分布式鎖的lockWatchdogTimeout超時,那麼這個鎖將變為失效狀態。這個參數可以用來避免由Redisson客戶端節點宕機或其他原因造成死鎖的情况。
keepPubSubOrder(保持訂閱發布順序)
默認值:true
通過該參數來修改是否按訂閱發布消息的接收順序出來消息,如果選否將對消息實行並行處理,該參數只適用於訂閱發布消息的情况。
performanceMode(高性能模式)
默認值:HIGHER_THROUGHPUT
用來指定高性能引擎的行為。由於該變量值的選用與使用場景息息相關(NORMAL除外)我們建議對每個參數值都進行嘗試。
該參數僅限於Redisson PRO版本。
可選模式:
HIGHER_THROUGHPUT - 將高性能引擎切換到 高通量 模式。
LOWER_LATENCY_AUTO - 將高性能引擎切換到 低延時 模式並自動探測最佳設定。
LOWER_LATENCY_MODE_1 - 將高性能引擎切換到 低延時 模式並調整到預設模式1。
LOWER_LATENCY_MODE_2 - 將高性能引擎切換到 低延時 模式並調整到預設模式2。
NORMAL - 將高性能引擎切換到 普通 模式
2.4. 集群模式
集群模式除了適用於Redis集群環境,也適用於任何雲計算服務商提供的集群模式,例如AWS ElastiCache集群版、Azure Redis Cache和阿裏雲(Aliyun)的雲數據庫Redis版。
程序化配置集群的用法:
Config config = new Config();
config.useClusterServers()
.setScanInterval(2000) // 集群狀態掃描間隔時間,單比特是毫秒
//可以用"rediss://"來啟用SSL連接,前綴必須是redis:// or rediss://
// 以下兩種寫法效果是一樣的
.addNodeAddress("redis://127.0.0.1:7000", "redis://127.0.0.1:7001")
.addNodeAddress("redis://127.0.0.1:7002");
RedissonClient redisson = Redisson.create(config);
2.4.1. 集群設置
介紹配置Redis集群組態的文檔在這裏。 Redis集群組態的最低要求是必須有三個主節點。Redisson的集群模式的使用方法如下:
ClusterServersConfig clusterConfig = config.useClusterServers();
ClusterServersConfig 類的設置參數如下:
nodeAddresses(添加節點地址)
可以通過host:port的格式來添加Redis集群節點的地址。多個節點可以一次性批量添加。
scanInterval(集群掃描間隔時間)
默認值: 1000
對Redis集群節點狀態掃描的時間間隔。單比特是毫秒。
slots(分片數量)
默認值: 231 用於指定數據分片過程中的分片數量。支持數據分片/框架結構有:集(Set)、映射(Map)、BitSet、Bloom filter, Spring Cache和Hibernate Cache等.
readMode(讀取操作的負載均衡模式)
默認值: SLAVE(只在從服務節點裏讀取)
注:在從服務節點裏讀取的數據說明已經至少有兩個節點保存了該數據,確保了數據的高可用性。
設置讀取操作選擇節點的模式。 可用值為: SLAVE - 只在從服務節點裏讀取。 MASTER - 只在主服務節點裏讀取。 MASTER_SLAVE - 在主從服務節點裏都可以讀取。
subscriptionMode(訂閱操作的負載均衡模式)
默認值:SLAVE(只在從服務節點裏訂閱)
設置訂閱操作選擇節點的模式。 可用值為: SLAVE - 只在從服務節點裏訂閱。 MASTER - 只在主服務節點裏訂閱。
loadBalancer(負載均衡算法類的選擇)
默認值: org.redisson.connection.balancer.RoundRobinLoadBalancer
在多Redis服務節點的環境裏,可以選用以下幾種負載均衡方式選擇一個節點: org.redisson.connection.balancer.WeightedRoundRobinBalancer - 權重輪詢調度算法 org.redisson.connection.balancer.RoundRobinLoadBalancer - 輪詢調度算法
org.redisson.connection.balancer.RandomLoadBalancer - 隨機調度算法
subscriptionConnectionMinimumIdleSize(從節點發布和訂閱連接的最小空閑連接數)
默認值:1
多從節點的環境裏,每個 從服務節點裏用於發布和訂閱連接的最小保持連接數(長連接)。Redisson內部經常通過發布和訂閱來實現許多功能。長期保持一定數量的發布訂閱連接是必須的。
subscriptionConnectionPoolSize(從節點發布和訂閱連接池大小)
默認值:50
多從節點的環境裏,每個 從服務節點裏用於發布和訂閱連接的連接池最大容量。連接池的連接數量自動彈性伸縮。
slaveConnectionMinimumIdleSize(從節點最小空閑連接數)
默認值:32
多從節點的環境裏,每個 從服務節點裏用於普通操作(非 發布和訂閱)的最小保持連接數(長連接)。長期保持一定數量的連接有利於提高瞬時讀取反映速度。
slaveConnectionPoolSize(從節點連接池大小)
默認值:64
多從節點的環境裏,每個 從服務節點裏用於普通操作(非 發布和訂閱)連接的連接池最大容量。連接池的連接數量自動彈性伸縮。
masterConnectionMinimumIdleSize(主節點最小空閑連接數)
默認值:32
多從節點的環境裏,每個 主節點的最小保持連接數(長連接)。長期保持一定數量的連接有利於提高瞬時寫入反應速度。
masterConnectionPoolSize(主節點連接池大小)
默認值:64
主節點的連接池最大容量。連接池的連接數量自動彈性伸縮。
idleConnectionTimeout(連接空閑超時,單比特:毫秒)
默認值:10000
如果當前連接池裏的連接數量超過了最小空閑連接數,而同時有連接空閑時間超過了該數值,那麼這些連接將會自動被關閉,並從連接池裏去掉。時間單比特是毫秒。
connectTimeout(連接超時,單比特:毫秒)
默認值:10000
同任何節點建立連接時的等待超時。時間單比特是毫秒。
timeout(命令等待超時,單比特:毫秒)
默認值:3000
等待節點回複命令的時間。該時間從命令發送成功時開始計時。
retryAttempts(命令失敗重試次數)
默認值:3
如果嘗試達到 retryAttempts(命令失敗重試次數) 仍然不能將命令發送至某個指定的節點時,將拋出錯誤。如果嘗試在此限制之內發送成功,則開始啟用 timeout(命令等待超時) 計時。
retryInterval(命令重試發送時間間隔,單比特:毫秒)
默認值:1500
在某個節點執行相同或不同命令時,連續 失敗 failedAttempts(執行失敗最大次數) 時,該節點將被從可用節點列錶裏清除,直到 reconnectionTimeout(重新連接時間間隔) 超時以後再次嘗試。
password(密碼)
默認值:null
用於節點身份驗證的密碼。
subscriptionsPerConnection(單個連接最大訂閱數量)
默認值:5
每個連接的最大訂閱數量。
clientName(客戶端名稱)
默認值:null
在Redis節點裏顯示的客戶端名稱。
sslEnableEndpointIdentification(啟用SSL終端識別)
默認值:true
開啟SSL終端識別能力。
sslProvider(SSL實現方式)
默認值:JDK
確定采用哪種方式(JDK或OPENSSL)來實現SSL連接。
sslTruststore(SSL信任證書庫路徑)
默認值:null
指定SSL信任證書庫的路徑。
sslTruststorePassword(SSL信任證書庫密碼)
默認值:null
指定SSL信任證書庫的密碼。
sslKeystore(SSL鑰匙庫路徑)
默認值:null
指定SSL鑰匙庫的路徑。
sslKeystorePassword(SSL鑰匙庫密碼)
默認值:null
指定SSL鑰匙庫的密碼。
2.4.2. 通過YAML文件配置集群模式
配置集群模式可以通過指定一個YAML格式的文件來實現。以下是YAML格式的配置文件樣本。文件中的字段名稱必須與ClusterServersConfig和Config對象裏的字段名稱相符。
---
clusterServersConfig:
idleConnectionTimeout: 10000
connectTimeout: 10000
timeout: 3000
retryAttempts: 3
retryInterval: 1500
password: null
subscriptionsPerConnection: 5
clientName: null
loadBalancer: !<org.redisson.connection.balancer.RoundRobinLoadBalancer> {
}
slaveSubscriptionConnectionMinimumIdleSize: 1
slaveSubscriptionConnectionPoolSize: 50
slaveConnectionMinimumIdleSize: 32
slaveConnectionPoolSize: 64
masterConnectionMinimumIdleSize: 32
masterConnectionPoolSize: 64
readMode: "SLAVE"
nodeAddresses:
- "redis://127.0.0.1:7004"
- "redis://127.0.0.1:7001"
- "redis://127.0.0.1:7000"
scanInterval: 1000
threads: 0
nettyThreads: 0
codec: !<org.redisson.codec.JsonJacksonCodec> {
}
"transportMode":"NIO"
2.5. 雲托管模式
雲托管模式適用於任何由雲計算運營商提供的Redis雲服務,包括亞馬遜雲的AWS ElastiCache、微軟雲的Azure Redis 緩存和阿裏雲(Aliyun)的雲數據庫Redis版
程序化配置雲托管模式的方法如下:
Config config = new Config();
config.useReplicatedServers()
.setScanInterval(2000) // 主節點變化掃描間隔時間
//可以用"rediss://"來啟用SSL連接
.addNodeAddress("redis://127.0.0.1:7000", "redis://127.0.0.1:7001")
.addNodeAddress("redis://127.0.0.1:7002");
RedissonClient redisson = Redisson.create(config);
2.5.1. 雲托管模式設置
Redisson的雲托管模式的使用方法如下: ReplicatedServersConfig replicatedConfig = config.useReplicatedServers();
ReplicatedServersConfig 類的設置參數如下:
nodeAddresses(節點地址)
可以通過host:port的格式來指定雲托管模式的多個Redis集群節點的地址。多個節點可以一次性批量添加。所有的主從節點必須在配置階段全部體現出來。
scanInterval(主節點變化掃描間隔時間)
默認值: 1000
對主節點變化節點狀態掃描的時間間隔。單比特是毫秒。
loadBalancer(負載均衡算法類的選擇)
默認值: org.redisson.connection.balancer.RoundRobinLoadBalancer
在使用多個Elasticache Redis服務節點的環境裏,可以選用以下幾種負載均衡方式選擇一個節點: org.redisson.connection.balancer.WeightedRoundRobinBalancer - 權重輪詢調度算法 org.redisson.connection.balancer.RoundRobinLoadBalancer - 輪詢調度算法 org.redisson.connection.balancer.RandomLoadBalancer - 隨機調度算法
dnsMonitoringInterval(DNS監控間隔,單比特:毫秒)
默認值:5000
用來指定檢查節點DNS變化的時間間隔。使用的時候應該確保JVM裏的DNS數據的緩存時間保持在足够低的範圍才有意義。用-1來禁用該功能。
subscriptionConnectionMinimumIdleSize(從節點發布和訂閱連接的最小空閑連接數)
默認值:1
多從節點的環境裏,每個 從服務節點裏用於發布和訂閱連接的最小保持連接數(長連接)。Redisson內部經常通過發布和訂閱來實現許多功能。長期保持一定數量的發布訂閱連接是必須的。
subscriptionConnectionPoolSize(從節點發布和訂閱連接池大小)
默認值:50
多從節點的環境裏,每個 從服務節點裏用於發布和訂閱連接的連接池最大容量。連接池的連接數量自動彈性伸縮。
slaveConnectionMinimumIdleSize(從節點最小空閑連接數)
默認值:32
多從節點的環境裏,每個 從服務節點裏用於普通操作(非 發布和訂閱)的最小保持連接數(長連接)。長期保持一定數量的連接有利於提高瞬時讀取反映速度。
slaveConnectionPoolSize(從節點連接池大小)
默認值:64
多從節點的環境裏,每個 從服務節點裏用於普通操作(非 發布和訂閱)連接的連接池最大容量。連接池的連接數量自動彈性伸縮。
masterConnectionMinimumIdleSize(主節點最小空閑連接數)
默認值:32
多從節點的環境裏,每個 主節點的最小保持連接數(長連接)。長期保持一定數量的連接有利於提高瞬時寫入反應速度。
masterConnectionPoolSize(主節點連接池大小)
默認值:64
主節點的連接池最大容量。連接池的連接數量自動彈性伸縮。
idleConnectionTimeout(連接空閑超時,單比特:毫秒)
默認值:10000
如果當前連接池裏的連接數量超過了最小空閑連接數,而同時有連接空閑時間超過了該數值,那麼這些連接將會自動被關閉,並從連接池裏去掉。時間單比特是毫秒。
readMode(讀取操作的負載均衡模式)
默認值: SLAVE(只在從服務節點裏讀取)
注:在從服務節點裏讀取的數據說明已經至少有兩個節點保存了該數據,確保了數據的高可用性。
設置讀取操作選擇節點的模式。 可用值為: SLAVE - 只在從服務節點裏讀取。 MASTER - 只在主服務節點裏讀取。 MASTER_SLAVE - 在主從服務節點裏都可以讀取。
subscriptionMode(訂閱操作的負載均衡模式)
默認值:SLAVE(只在從服務節點裏訂閱)
設置訂閱操作選擇節點的模式。 可用值為: SLAVE - 只在從服務節點裏訂閱。 MASTER - 只在主服務節點裏訂閱。
connectTimeout(連接超時,單比特:毫秒)
默認值:10000
同任何節點建立連接時的等待超時。時間單比特是毫秒。
timeout(命令等待超時,單比特:毫秒)
默認值:3000
等待節點回複命令的時間。該時間從命令發送成功時開始計時。
retryAttempts(命令失敗重試次數)
默認值:3
如果嘗試達到 retryAttempts(命令失敗重試次數) 仍然不能將命令發送至某個指定的節點時,將拋出錯誤。如果嘗試在此限制之內發送成功,則開始啟用 timeout(命令等待超時) 計時。
retryInterval(命令重試發送時間間隔,單比特:毫秒)
默認值:1500
在某個節點執行相同或不同命令時,連續 失敗 failedAttempts(執行失敗最大次數) 時,該節點將被從可用節點列錶裏清除,直到 reconnectionTimeout(重新連接時間間隔) 超時以後再次嘗試。
database(數據庫編號)
默認值:0
嘗試連接的數據庫編號。
password(密碼)
默認值:null
用於節點身份驗證的密碼。
subscriptionsPerConnection(單個連接最大訂閱數量)
默認值:5
每個連接的最大訂閱數量。
clientName(客戶端名稱)
默認值:null
在Redis節點裏顯示的客戶端名稱。
sslEnableEndpointIdentification(啟用SSL終端識別)
默認值:true
開啟SSL終端識別能力。
sslProvider(SSL實現方式)
默認值:JDK
確定采用哪種方式(JDK或OPENSSL)來實現SSL連接。
sslTruststore(SSL信任證書庫路徑)
默認值:null
指定SSL信任證書庫的路徑。
sslTruststorePassword(SSL信任證書庫密碼)
默認值:null
指定SSL信任證書庫的密碼。
sslKeystore(SSL鑰匙庫路徑)
默認值:null
指定SSL鑰匙庫的路徑。
sslKeystorePassword(SSL鑰匙庫密碼)
默認值:null
指定SSL鑰匙庫的密碼。
2.5.2. 通過YAML文件配置集群模式
配置雲托管模式可以通過指定一個YAML格式的文件來實現。以下是YAML格式的配置文件樣本。文件中的字段名稱必須與ReplicatedServersConfig 和Config對象裏的字段名稱相符。
---
replicatedServersConfig:
idleConnectionTimeout: 10000
connectTimeout: 10000
timeout: 3000
retryAttempts: 3
retryInterval: 1500
password: null
subscriptionsPerConnection: 5
clientName: null
loadBalancer: !<org.redisson.connection.balancer.RoundRobinLoadBalancer> {
}
slaveSubscriptionConnectionMinimumIdleSize: 1
slaveSubscriptionConnectionPoolSize: 50
slaveConnectionMinimumIdleSize: 32
slaveConnectionPoolSize: 64
masterConnectionMinimumIdleSize: 32
masterConnectionPoolSize: 64
readMode: "SLAVE"
nodeAddresses:
- "redis://127.0.0.1:2812"
- "redis://127.0.0.1:2815"
- "redis://127.0.0.1:2813"
scanInterval: 1000
threads: 0
nettyThreads: 0
codec: !<org.redisson.codec.JsonJacksonCodec> {
}
"transportMode":"NIO"
2.6. 單Redis節點模式
程序化配置方法:
// 默認連接地址 127.0.0.1:6379
RedissonClient redisson = Redisson.create();
Config config = new Config();
config.useSingleServer().setAddress("redis://myredisserver:6379");
RedissonClient redisson = Redisson.create(config);
2.6.1. 單節點設置
Redis程序的配置和架設文檔在這裏。Redisson的單Redis節點模式的使用方法如下: SingleServerConfig singleConfig = config.useSingleServer();
SingleServerConfig 類的設置參數如下:
address(節點地址)
可以通過host:port的格式來指定節點地址。
subscriptionConnectionMinimumIdleSize(發布和訂閱連接的最小空閑連接數)
默認值:1
用於發布和訂閱連接的最小保持連接數(長連接)。Redisson內部經常通過發布和訂閱來實現許多功能。長期保持一定數量的發布訂閱連接是必須的。
subscriptionConnectionPoolSize(發布和訂閱連接池大小)
默認值:50
用於發布和訂閱連接的連接池最大容量。連接池的連接數量自動彈性伸縮。
connectionMinimumIdleSize(最小空閑連接數)
默認值:32
最小保持連接數(長連接)。長期保持一定數量的連接有利於提高瞬時寫入反應速度。
connectionPoolSize(連接池大小)
默認值:64
在啟用該功能以後,Redisson將會監測DNS的變化情况。
dnsMonitoringInterval(DNS監測時間間隔,單比特:毫秒)
默認值:5000
監測DNS的變化情况的時間間隔。
idleConnectionTimeout(連接空閑超時,單比特:毫秒)
默認值:10000
如果當前連接池裏的連接數量超過了最小空閑連接數,而同時有連接空閑時間超過了該數值,那麼這些連接將會自動被關閉,並從連接池裏去掉。時間單比特是毫秒。
connectTimeout(連接超時,單比特:毫秒)
默認值:10000
同節點建立連接時的等待超時。時間單比特是毫秒。
timeout(命令等待超時,單比特:毫秒)
默認值:3000
等待節點回複命令的時間。該時間從命令發送成功時開始計時。
retryAttempts(命令失敗重試次數)
默認值:3
如果嘗試達到 retryAttempts(命令失敗重試次數) 仍然不能將命令發送至某個指定的節點時,將拋出錯誤。如果嘗試在此限制之內發送成功,則開始啟用 timeout(命令等待超時) 計時。
retryInterval(命令重試發送時間間隔,單比特:毫秒)
默認值:1500
在某個節點執行相同或不同命令時,連續 失敗 failedAttempts(執行失敗最大次數) 時,該節點將被從可用節點列錶裏清除,直到 reconnectionTimeout(重新連接時間間隔) 超時以後再次嘗試。
database(數據庫編號)
默認值:0
嘗試連接的數據庫編號。
password(密碼)
默認值:null
用於節點身份驗證的密碼。
subscriptionsPerConnection(單個連接最大訂閱數量)
默認值:5
每個連接的最大訂閱數量。
clientName(客戶端名稱)
默認值:null
在Redis節點裏顯示的客戶端名稱。
sslEnableEndpointIdentification(啟用SSL終端識別)
默認值:true
開啟SSL終端識別能力。
sslProvider(SSL實現方式)
默認值:JDK
確定采用哪種方式(JDK或OPENSSL)來實現SSL連接。
sslTruststore(SSL信任證書庫路徑)
默認值:null
指定SSL信任證書庫的路徑。
sslTruststorePassword(SSL信任證書庫密碼)
默認值:null
指定SSL信任證書庫的密碼。
sslKeystore(SSL鑰匙庫路徑)
默認值:null
指定SSL鑰匙庫的路徑。
sslKeystorePassword(SSL鑰匙庫密碼)
默認值:null
指定SSL鑰匙庫的密碼。
2.6.2. 通過YAML文件配置集群模式
配置單節點模式可以通過指定一個YAML格式的文件來實現。以下是YAML格式的配置文件樣本。文件中的字段名稱必須與SingleServerConfig和Config對象裏的字段名稱相符。
---
singleServerConfig:
idleConnectionTimeout: 10000
connectTimeout: 10000
timeout: 3000
retryAttempts: 3
retryInterval: 1500
password: null
subscriptionsPerConnection: 5
clientName: null
address: "redis://127.0.0.1:6379"
subscriptionConnectionMinimumIdleSize: 1
subscriptionConnectionPoolSize: 50
connectionMinimumIdleSize: 32
connectionPoolSize: 64
database: 0
dnsMonitoringInterval: 5000
threads: 0
nettyThreads: 0
codec: !<org.redisson.codec.JsonJacksonCodec> {
}
"transportMode":"NIO"
2.7. 哨兵模式
程序化配置哨兵模式的方法如下:
Config config = new Config();
config.useSentinelServers()
.setMasterName("mymaster")
//可以用"rediss://"來啟用SSL連接
.addSentinelAddress("redis://127.0.0.1:26389", "redis://127.0.0.1:26379")
.addSentinelAddress("redis://127.0.0.1:26319");
RedissonClient redisson = Redisson.create(config);
2.7.1. 哨兵模式設置
配置Redis哨兵服務的官方文檔在這裏。Redisson的哨兵模式的使用方法如下: SentinelServersConfig sentinelConfig = config.useSentinelServers();
SentinelServersConfig 類的設置參數如下:
dnsMonitoringInterval(DNS監控間隔,單比特:毫秒)
默認值:5000
用來指定檢查節點DNS變化的時間間隔。使用的時候應該確保JVM裏的DNS數據的緩存時間保持在足够低的範圍才有意義。用-1來禁用該功能。
masterName(主服務器的名稱)
主服務器的名稱是哨兵進程中用來監測主從服務切換情况的。
addSentinelAddress(添加哨兵節點地址)
可以通過host:port的格式來指定哨兵節點的地址。多個節點可以一次性批量添加。
readMode(讀取操作的負載均衡模式)
默認值: SLAVE(只在從服務節點裏讀取)
注:在從服務節點裏讀取的數據說明已經至少有兩個節點保存了該數據,確保了數據的高可用性。
設置讀取操作選擇節點的模式。 可用值為: SLAVE - 只在從服務節點裏讀取。 MASTER - 只在主服務節點裏讀取。 MASTER_SLAVE - 在主從服務節點裏都可以讀取。
subscriptionMode(訂閱操作的負載均衡模式)
默認值:SLAVE(只在從服務節點裏訂閱)
設置訂閱操作選擇節點的模式。 可用值為: SLAVE - 只在從服務節點裏訂閱。 MASTER - 只在主服務節點裏訂閱。
loadBalancer(負載均衡算法類的選擇)
默認值: org.redisson.connection.balancer.RoundRobinLoadBalancer
在使用多個Redis服務節點的環境裏,可以選用以下幾種負載均衡方式選擇一個節點: org.redisson.connection.balancer.WeightedRoundRobinBalancer - 權重輪詢調度算法 org.redisson.connection.balancer.RoundRobinLoadBalancer - 輪詢調度算法 org.redisson.connection.balancer.RandomLoadBalancer - 隨機調度算法
subscriptionConnectionMinimumIdleSize(從節點發布和訂閱連接的最小空閑連接數)
默認值:1
多從節點的環境裏,每個 從服務節點裏用於發布和訂閱連接的最小保持連接數(長連接)。Redisson內部經常通過發布和訂閱來實現許多功能。長期保持一定數量的發布訂閱連接是必須的。
subscriptionConnectionPoolSize(從節點發布和訂閱連接池大小)
默認值:50
多從節點的環境裏,每個 從服務節點裏用於發布和訂閱連接的連接池最大容量。連接池的連接數量自動彈性伸縮。
slaveConnectionMinimumIdleSize(從節點最小空閑連接數)
默認值:32
多從節點的環境裏,每個 從服務節點裏用於普通操作(非 發布和訂閱)的最小保持連接數(長連接)。長期保持一定數量的連接有利於提高瞬時讀取反映速度。
slaveConnectionPoolSize(從節點連接池大小)
默認值:64
多從節點的環境裏,每個 從服務節點裏用於普通操作(非 發布和訂閱)連接的連接池最大容量。連接池的連接數量自動彈性伸縮。
masterConnectionMinimumIdleSize(主節點最小空閑連接數)
默認值:32
多從節點的環境裏,每個 主節點的最小保持連接數(長連接)。長期保持一定數量的連接有利於提高瞬時寫入反應速度。
masterConnectionPoolSize(主節點連接池大小)
默認值:64
主節點的連接池最大容量。連接池的連接數量自動彈性伸縮。
idleConnectionTimeout(連接空閑超時,單比特:毫秒)
默認值:10000
如果當前連接池裏的連接數量超過了最小空閑連接數,而同時有連接空閑時間超過了該數值,那麼這些連接將會自動被關閉,並從連接池裏去掉。時間單比特是毫秒。
connectTimeout(連接超時,單比特:毫秒)
默認值:10000
同任何節點建立連接時的等待超時。時間單比特是毫秒。
timeout(命令等待超時,單比特:毫秒)
默認值:3000
等待節點回複命令的時間。該時間從命令發送成功時開始計時。
retryAttempts(命令失敗重試次數)
默認值:3
如果嘗試達到 retryAttempts(命令失敗重試次數) 仍然不能將命令發送至某個指定的節點時,將拋出錯誤。如果嘗試在此限制之內發送成功,則開始啟用 timeout(命令等待超時) 計時。
retryInterval(命令重試發送時間間隔,單比特:毫秒)
默認值:1500
在某個節點執行相同或不同命令時,連續 失敗 failedAttempts(執行失敗最大次數) 時,該節點將被從可用節點列錶裏清除,直到 reconnectionTimeout(重新連接時間間隔) 超時以後再次嘗試。
database(數據庫編號)
默認值:0
嘗試連接的數據庫編號。
password(密碼)
默認值:null
用於節點身份驗證的密碼。
subscriptionsPerConnection(單個連接最大訂閱數量)
默認值:5
每個連接的最大訂閱數量。
clientName(客戶端名稱)
默認值:null
在Redis節點裏顯示的客戶端名稱。
sslEnableEndpointIdentification(啟用SSL終端識別)
默認值:true
開啟SSL終端識別能力。
sslProvider(SSL實現方式)
默認值:JDK
確定采用哪種方式(JDK或OPENSSL)來實現SSL連接。
sslTruststore(SSL信任證書庫路徑)
默認值:null
指定SSL信任證書庫的路徑。
sslTruststorePassword(SSL信任證書庫密碼)
默認值:null
指定SSL信任證書庫的密碼。
sslKeystore(SSL鑰匙庫路徑)
默認值:null
指定SSL鑰匙庫的路徑。
sslKeystorePassword(SSL鑰匙庫密碼)
默認值:null
指定SSL鑰匙庫的密碼。
2.7.2. 通過YAML文件配置集群模式
配置哨兵模式可以通過指定一個YAML格式的文件來實現。以下是YAML格式的配置文件樣本。文件中的字段名稱必須與SentinelServersConfig和Config對象裏的字段名稱相符。
---
sentinelServersConfig:
idleConnectionTimeout: 10000
connectTimeout: 10000
timeout: 3000
retryAttempts: 3
retryInterval: 1500
password: null
subscriptionsPerConnection: 5
clientName: null
loadBalancer: !<org.redisson.connection.balancer.RoundRobinLoadBalancer> {
}
slaveSubscriptionConnectionMinimumIdleSize: 1
slaveSubscriptionConnectionPoolSize: 50
slaveConnectionMinimumIdleSize: 32
slaveConnectionPoolSize: 64
masterConnectionMinimumIdleSize: 32
masterConnectionPoolSize: 64
readMode: "SLAVE"
sentinelAddresses:
- "redis://127.0.0.1:26379"
- "redis://127.0.0.1:26389"
masterName: "mymaster"
database: 0
threads: 0
nettyThreads: 0
codec: !<org.redisson.codec.JsonJacksonCodec> {
}
"transportMode":"NIO"
2.8. 主從模式
程序化配置主從模式的用法:
Config config = new Config();
config.useMasterSlaveServers()
//可以用"rediss://"來啟用SSL連接
.setMasterAddress("redis://127.0.0.1:6379")
.addSlaveAddress("redis://127.0.0.1:6389", "redis://127.0.0.1:6332", "redis://127.0.0.1:6419")
.addSlaveAddress("redis://127.0.0.1:6399");
RedissonClient redisson = Redisson.create(config);
2.8.1. 主從模式設置
介紹配置Redis主從服務組態的文檔在這裏. Redisson的主從模式的使用方法如下: MasterSlaveServersConfig masterSlaveConfig = config.useMasterSlaveServers();
MasterSlaveServersConfig 類的設置參數如下:
dnsMonitoringInterval(DNS監控間隔,單比特:毫秒)
默認值:5000
用來指定檢查節點DNS變化的時間間隔。使用的時候應該確保JVM裏的DNS數據的緩存時間保持在足够低的範圍才有意義。用-1來禁用該功能。
masterAddress(主節點地址)
可以通過host:port的格式來指定主節點地址。
addSlaveAddress(添加從主節點地址)
可以通過host:port的格式來指定從節點的地址。多個節點可以一次性批量添加。
readMode(讀取操作的負載均衡模式)
默認值: SLAVE(只在從服務節點裏讀取)
注:在從服務節點裏讀取的數據說明已經至少有兩個節點保存了該數據,確保了數據的高可用性。
設置讀取操作選擇節點的模式。 可用值為: SLAVE - 只在從服務節點裏讀取。 MASTER - 只在主服務節點裏讀取。 MASTER_SLAVE - 在主從服務節點裏都可以讀取。
subscriptionMode(訂閱操作的負載均衡模式)
默認值:SLAVE(只在從服務節點裏訂閱)
設置訂閱操作選擇節點的模式。 可用值為: SLAVE - 只在從服務節點裏訂閱。 MASTER - 只在主服務節點裏訂閱。
loadBalancer(負載均衡算法類的選擇)
默認值: org.redisson.connection.balancer.RoundRobinLoadBalancer
在使用多個Redis服務節點的環境裏,可以選用以下幾種負載均衡方式選擇一個節點: org.redisson.connection.balancer.WeightedRoundRobinBalancer - 權重輪詢調度算法 org.redisson.connection.balancer.RoundRobinLoadBalancer - 輪詢調度算法 org.redisson.connection.balancer.RandomLoadBalancer - 隨機調度算法
subscriptionConnectionMinimumIdleSize(從節點發布和訂閱連接的最小空閑連接數)
默認值:1
多從節點的環境裏,每個 從服務節點裏用於發布和訂閱連接的最小保持連接數(長連接)。Redisson內部經常通過發布和訂閱來實現許多功能。長期保持一定數量的發布訂閱連接是必須的。
subscriptionConnectionPoolSize(從節點發布和訂閱連接池大小)
默認值:50
多從節點的環境裏,每個 從服務節點裏用於發布和訂閱連接的連接池最大容量。連接池的連接數量自動彈性伸縮。
slaveConnectionMinimumIdleSize(從節點最小空閑連接數)
默認值:32
多從節點的環境裏,每個 從服務節點裏用於普通操作(非 發布和訂閱)的最小保持連接數(長連接)。長期保持一定數量的連接有利於提高瞬時讀取反映速度。
slaveConnectionPoolSize(從節點連接池大小)
默認值:64
多從節點的環境裏,每個 從服務節點裏用於普通操作(非 發布和訂閱)連接的連接池最大容量。連接池的連接數量自動彈性伸縮。
masterConnectionMinimumIdleSize(主節點最小空閑連接數)
默認值:32
多從節點的環境裏,每個 主節點的最小保持連接數(長連接)。長期保持一定數量的連接有利於提高瞬時寫入反應速度。
masterConnectionPoolSize(主節點連接池大小)
默認值:64
主節點的連接池最大容量。連接池的連接數量自動彈性伸縮。
idleConnectionTimeout(連接空閑超時,單比特:毫秒)
默認值:10000
如果當前連接池裏的連接數量超過了最小空閑連接數,而同時有連接空閑時間超過了該數值,那麼這些連接將會自動被關閉,並從連接池裏去掉。時間單比特是毫秒。
connectTimeout(連接超時,單比特:毫秒)
默認值:10000
同任何節點建立連接時的等待超時。時間單比特是毫秒。
timeout(命令等待超時,單比特:毫秒)
默認值:3000
等待節點回複命令的時間。該時間從命令發送成功時開始計時。
retryAttempts(命令失敗重試次數)
默認值:3
如果嘗試達到 retryAttempts(命令失敗重試次數) 仍然不能將命令發送至某個指定的節點時,將拋出錯誤。如果嘗試在此限制之內發送成功,則開始啟用 timeout(命令等待超時) 計時。
retryInterval(命令重試發送時間間隔,單比特:毫秒)
默認值:1500
在某個節點執行相同或不同命令時,連續 失敗 failedAttempts(執行失敗最大次數) 時,該節點將被從可用節點列錶裏清除,直到 reconnectionTimeout(重新連接時間間隔) 超時以後再次嘗試。
database(數據庫編號)
默認值:0
嘗試連接的數據庫編號。
password(密碼)
默認值:null
用於節點身份驗證的密碼。
subscriptionsPerConnection(單個連接最大訂閱數量)
默認值:5
每個連接的最大訂閱數量。
clientName(客戶端名稱)
默認值:null
在Redis節點裏顯示的客戶端名稱。
sslEnableEndpointIdentification(啟用SSL終端識別)
默認值:true
開啟SSL終端識別能力。
sslProvider(SSL實現方式)
默認值:JDK
確定采用哪種方式(JDK或OPENSSL)來實現SSL連接。
sslTruststore(SSL信任證書庫路徑)
默認值:null
指定SSL信任證書庫的路徑。
sslTruststorePassword(SSL信任證書庫密碼)
默認值:null
指定SSL信任證書庫的密碼。
sslKeystore(SSL鑰匙庫路徑)
默認值:null
指定SSL鑰匙庫的路徑。
sslKeystorePassword(SSL鑰匙庫密碼)
默認值:null
指定SSL鑰匙庫的密碼。
2.8.2. 通過YAML文件配置集群模式
配置主從模式可以通過指定一個YAML格式的文件來實現。以下是YAML格式的配置文件樣本。文件中的字段名稱必須與MasterSlaveServersConfig和Config對象裏的字段名稱相符。
---
masterSlaveServersConfig:
idleConnectionTimeout: 10000
connectTimeout: 10000
timeout: 3000
retryAttempts: 3
retryInterval: 1500
failedAttempts: 3
password: null
subscriptionsPerConnection: 5
clientName: null
loadBalancer: !<org.redisson.connection.balancer.RoundRobinLoadBalancer> {
}
slaveSubscriptionConnectionMinimumIdleSize: 1
slaveSubscriptionConnectionPoolSize: 50
slaveConnectionMinimumIdleSize: 32
slaveConnectionPoolSize: 64
masterConnectionMinimumIdleSize: 32
masterConnectionPoolSize: 64
readMode: "SLAVE"
slaveAddresses:
- "redis://127.0.0.1:6381"
- "redis://127.0.0.1:6380"
masterAddress: "redis://127.0.0.1:6379"
database: 0
threads: 0
nettyThreads: 0
codec: !<org.redisson.codec.JsonJacksonCodec> {
}
"transportMode":"NIO"
三、程序接口調用方式
RedissonClient、RedissonReactiveClient和RedissonRxClient實例本身和Redisson提供的所有分布式對象都是線程安全的。
Redisson為每個操作都提供了自動重試策略,當某個命令執行失敗時,Redisson會自動進行重試。自動重試策略可以通過修改retryAttempts(默認值:3)參數和retryInterval(默認值:1000毫秒)參數來進行優化調整。當等待時間達到retryInterval指定的時間間隔以後,將自動重試下一次。全部重試失敗以後將拋出錯誤。
Redisson框架提供的幾乎所有對象都包含了同步和异步相互匹配的方法。這些對象都可以通過RedissonClient接口獲取。同時還為大部分Redisson對象提供了滿足异步流處理標准的程序接口RedissonReactiveClient。除此外還提供了RxJava2規範的RedissonRxClient程序接口。
以下是關於使用RAtomicLong對象的範例:
RedissonClient client = Redisson.create(config);
RAtomicLong longObject = client.getAtomicLong('myLong');
// 同步執行方式
longObject.compareAndSet(3, 401);
// 异步執行方式
RFuture<Boolean> result = longObject.compareAndSetAsync(3, 401);
RedissonReactiveClient client = Redisson.createReactive(config);
RAtomicLongReactive longObject = client.getAtomicLong('myLong');
// 异步流執行方式
Mono<Boolean> result = longObject.compareAndSet(3, 401);
RedissonRxClient client = Redisson.createRx(config);
RAtomicLongRx longObject= client.getAtomicLong("myLong");
// RxJava2方式
Flowable<Boolean result = longObject.compareAndSet(3, 401);
3.1. 异步執行方式
幾乎所有的Redisson對象都實現了一個异步接口,异步接口提供的方法名稱與其同步接口的方法名稱相互匹配。例如:
// RAtomicLong接口繼承了RAtomicLongAsync接口
RAtomicLongAsync longObject = client.getAtomicLong("myLong");
RFuture<Boolean> future = longObject.compareAndSetAsync(1, 401);
异步執行的方法都會返回一個實現了RFuture接口的對象。該對象同時提供了java.util.concurrent.CompletionStage和java.util.concurrent.Future兩個异步接口。
future.whenComplete((res, exception) -> {
// ...
});
// 或者
future.thenAccept(res -> {
// 處理返回
}).exceptionally(exception -> {
// 處理錯誤
});
3.2. 异步流執行方式
Redisson為大多數分布式數據結構提供了滿足Reactor項目的异步流處理標准的程序接口。該接口通過兩種方式實現:
1.基於Project Reactor標准的實現方式。使用範例如下:
RedissonReactiveClient client = Redisson.createReactive(config);
RAtomicLongReactive atomicLong = client.getAtomicLong("myLong");
Mono<Boolean> cs = longObject.compareAndSet(10, 91);
Mono<Long> get = longObject.get();
Publisher<Long> getPublisher = longObject.get();
2.基於RxJava2標准的實現方式。使用範例如下:
RedissonRxClient client = Redisson.createRx(config);
RAtomicLongRx atomicLong = client.getAtomicLong("myLong");
Single<Boolean> cs = longObject.compareAndSet(10, 91);
Single<Long> get = longObject.get();
四、數據序列化
Redisson的對象編碼類是用於將對象進行序列化和反序列化,以實現對該對象在Redis裏的讀取和存儲。Redisson提供了以下幾種的對象編碼應用,以供大家選擇:
編碼類名稱 | 說明 |
---|---|
org.redisson.codec.JsonJacksonCodec | Jackson JSON 編碼 默認編碼 |
org.redisson.codec.AvroJacksonCodec | Avro 一個二進制的JSON編碼 |
org.redisson.codec.SmileJacksonCodec | Smile 另一個二進制的JSON編碼 |
org.redisson.codec.CborJacksonCodec | CBOR 又一個二進制的JSON編碼 |
org.redisson.codec.MsgPackJacksonCodec | MsgPack 再來一個二進制的JSON編碼 |
org.redisson.codec.IonJacksonCodec | Amazon Ion 亞馬遜的Ion編碼,格式與JSON類似 |
org.redisson.codec.KryoCodec | Kryo 二進制對象序列化編碼 |
org.redisson.codec.SerializationCodec | JDK序列化編碼 |
org.redisson.codec.FstCodec | FST 10倍於JDK序列化性能而且100%兼容的編碼 |
org.redisson.codec.LZ4Codec | LZ4 壓縮型序列化對象編碼 |
org.redisson.codec.SnappyCodec | Snappy 另一個壓縮型序列化對象編碼 |
org.redisson.client.codec.JsonJacksonMapCodec | 基於Jackson的映射類使用的編碼。可用於避免序列化類的信息,以及用於解决使用byte[]遇到的問題。 |
org.redisson.client.codec.StringCodec | 純字符串編碼(無轉換) |
org.redisson.client.codec.LongCodec | 純整長型數字編碼(無轉換) |
org.redisson.client.codec.ByteArrayCodec | 字節數組編碼 |
org.redisson.codec.CompositeCodec | 用來組合多種不同編碼在一起 |
五、單個集合數據分片(Sharding)
在集群模式下,Redisson為單個Redis集合類型提供了自動分片的功能。
Redisson提供的所有數據結構都支持在集群環境下使用,但每個數據結構只被保存在一個固定的槽內。Redisson PRO提供的自動分片功能能够將單個數據結構拆分,然後均勻的分布在整個集群裏,而不是被擠在單一一個槽裏。自動分片功能的優勢主要有以下幾點:
- 單個數據結構可以充分利用整個集群內存資源,而不是被某一個節點的內存限制。
- 將單個數據結構分片以後分布在集群中不同的節點裏,不僅可以大幅提高讀寫性能,還能够保證讀寫性能隨著集群的擴張而自動提昇。
Redisson通過自身的分片算法,將一個大集合拆分為若幹個片段(默認231個,分片數量範圍是3 - 16834),然後將拆分後的片段均勻的分布到集群裏各個節點裏,保證每個節點分配到的片段數量大體相同。比如在默認情况下231個片段分到含有4個主節點的集群裏,每個主節點將會分配到大約57個片段,同樣的道理如果有5個主節點,每個節點會分配到大約46個片段。
目前支持的數據結構類型和服務包括集(Set)、映射(Map)、BitSet、布隆過濾器(Bloom Filter)、Spring Cache和Hibernate Cache。
該功能僅限於Redisson PRO版本。
六、分布式對象
每個Redisson對象實例都會有一個與之對應的Redis數據實例,可以通過調用getName方法來取得Redis數據實例的名稱(key)。
RMap map = redisson.getMap("mymap");
map.getName(); // = mymap
所有與Redis key相關的操作都歸納在RKeys這個接口裏:
RKeys keys = redisson.getKeys();
Iterable<String> allKeys = keys.getKeys();
Iterable<String> foundedKeys = keys.getKeysByPattern('key*');
long numOfDeletedKeys = keys.delete("obj1", "obj2", "obj3");
long deletedKeysAmount = keys.deleteByPattern("test?");
String randomKey = keys.randomKey();
long keysAmount = keys.count();
6.1. 通用對象桶(Object Bucket)
Redisson的分布式RBucketJava對象是一種通用對象桶可以用來存放任類型的對象。 除了同步接口外,還提供了异步(Async)、反射式(Reactive)和RxJava2標准的接口。
RBucket<AnyObject> bucket = redisson.getBucket("anyObject");
bucket.set(new AnyObject(1));
AnyObject obj = bucket.get();
bucket.trySet(new AnyObject(3));
bucket.compareAndSet(new AnyObject(4), new AnyObject(5));
bucket.getAndSet(new AnyObject(6));
還可以通過RBuckets接口實現批量操作多個RBucket對象:
RBuckets buckets = redisson.getBuckets();
List<RBucket<V>> foundBuckets = buckets.find("myBucket*");
Map<String, V> loadedBuckets = buckets.get("myBucket1", "myBucket2", "myBucket3");
Map<String, Object> map = new HashMap<>();
map.put("myBucket1", new MyObject());
map.put("myBucket2", new MyObject());
// 利用Redis的事務特性,同時保存所有的通用對象桶,如果任意一個通用對象桶已經存在則放弃保存其他所有數據。
buckets.trySet(map);
// 同時保存全部通用對象桶。
buckets.set(map);
6.2. 二進制流(Binary Stream)
Redisson的分布式RBinaryStream Java對象同時提供了InputStream接口和OutputStream接口的實現。流的最大容量受Redis主節點的內存大小限制。
RBinaryStream stream = redisson.getBinaryStream("anyStream");
byte[] content = ...
stream.set(content);
InputStream is = stream.getInputStream();
byte[] readBuffer = new byte[512];
is.read(readBuffer);
OutputStream os = stream.getOuputStream();
byte[] contentToWrite = ...
os.write(contentToWrite);
6.3. 地理空間對象桶(Geospatial Bucket)
Redisson的分布式RGeo Java對象是一種專門用來儲存與地理比特置有關的對象桶。除了同步接口外,還提供了异步(Async)、反射式(Reactive)和RxJava2標准的接口。
RGeo<String> geo = redisson.getGeo("test");
geo.add(new GeoEntry(13.361389, 38.115556, "Palermo"),
new GeoEntry(15.087269, 37.502669, "Catania"));
geo.addAsync(37.618423, 55.751244, "Moscow");
Double distance = geo.dist("Palermo", "Catania", GeoUnit.METERS);
geo.hashAsync("Palermo", "Catania");
Map<String, GeoPosition> positions = geo.pos("test2", "Palermo", "test3", "Catania", "test1");
List<String> cities = geo.radius(15, 37, 200, GeoUnit.KILOMETERS);
Map<String, GeoPosition> citiesWithPositions = geo.radiusWithPosition(15, 37, 200, GeoUnit.KILOMETERS);
6.4. BitSet
Redisson的分布式RBitSetJava對象采用了與java.util.BiteSet類似結構的設計風格。可以理解為它是一個分布式的可伸縮式比特向量。需要注意的是RBitSet的大小受Redis限制,最大長度為4 294 967 295。除了同步接口外,還提供了异步(Async)、反射式(Reactive)和RxJava2標准的接口。
RBitSet set = redisson.getBitSet("simpleBitset");
set.set(0, true);
set.set(1812, false);
set.clear(0);
set.addAsync("e");
set.xor("anotherBitset");
6.4.1. BitSet數據分片(Sharding)(分布式RoaringBitMap)
基於Redis的Redisson集群分布式BitSet通過RClusteredBitSet接口,為集群狀態下的Redis環境提供了BitSet數據分片的功能。通過優化後更加有效的分布式RoaringBitMap算法,突破了原有的BitSet大小限制,達到了集群物理內存容量大小。在這裏可以獲取更多的內部信息。
RClusteredBitSet set = redisson.getClusteredBitSet("simpleBitset");
set.set(0, true);
set.set(1812, false);
set.clear(0);
set.addAsync("e");
set.xor("anotherBitset");
該功能僅限於Redisson PRO版本。
6.5. 原子整長形(AtomicLong)
Redisson的分布式整長形RAtomicLong對象和Java中的java.util.concurrent.atomic.AtomicLong對象類似。除了同步接口外,還提供了异步(Async)、反射式(Reactive)和RxJava2標准的接口。
RAtomicLong atomicLong = redisson.getAtomicLong("myAtomicLong");
atomicLong.set(3);
atomicLong.incrementAndGet();
atomicLong.get();
6.6. 原子雙精度浮點(AtomicDouble)
Redisson還提供了分布式原子雙精度浮點RAtomicDouble,彌補了Java自身的不足。除了同步接口外,還提供了异步(Async)、反射式(Reactive)和RxJava2標准的接口。
RAtomicDouble atomicDouble = redisson.getAtomicDouble("myAtomicDouble");
atomicDouble.set(2.81);
atomicDouble.addAndGet(4.11);
atomicDouble.get();
6.7. 話題(訂閱分發)
Redisson的分布式話題RTopic(http://static.javadoc.io/org.redisson/redisson/3.10.0/org/redisson/api/RTopic.html對象實現了發布、訂閱的機制。除了同步接口外,還提供了异步(Async(http://static.javadoc.io/org.redisson/redisson/3.10.0/org/redisson/api/RTopicAsync.html))、反射式(Reactive(http://static.javadoc.io/org.redisson/redisson/3.10.0/org/redisson/api/RTopicReactive.html))和RxJava2(http://static.javadoc.io/org.redisson/redisson/3.10.0/org/redisson/api/RTopicRx.html)標准的接口。
RTopic topic = redisson.getTopic("anyTopic");
topic.addListener(SomeObject.class, new MessageListener<SomeObject>() {
@Override
public void onMessage(String channel, SomeObject message) {
//...
}
});
// 在其他線程或JVM節點
RTopic topic = redisson.getTopic("anyTopic");
long clientsReceivedMessage = topic.publish(new SomeObject());
在Redis節點故障轉移(主從切換)或斷線重連以後,所有的話題監聽器將自動完成話題的重新訂閱。
6.7.1. 模糊話題
Redisson的模糊話題RPatternTopic對象可以通過正式錶達式來訂閱多個話題。除了同步接口外,還提供了异步(Async)、反射式(Reactive)和RxJava2標准的接口。
// 訂閱所有滿足`topic1.*`錶達式的話題
RPatternTopic topic1 = redisson.getPatternTopic("topic1.*");
int listenerId = topic1.addListener(Message.class, new PatternMessageListener<Message>() {
@Override
public void onMessage(String pattern, String channel, Message msg) {
Assert.fail();
}
});
在Redis節點故障轉移(主從切換)或斷線重連以後,所有的模糊話題監聽器將自動完成話題的重新訂閱。
6.8. 布隆過濾器(Bloom Filter)
Redisson利用Redis實現了Java分布式布隆過濾器(Bloom Filter)。所含最大比特數量為232。
RBloomFilter<SomeObject> bloomFilter = redisson.getBloomFilter("sample");
// 初始化布隆過濾器,預計統計元素數量為55000000,期望誤差率為0.03
bloomFilter.tryInit(55000000L, 0.03);
bloomFilter.add(new SomeObject("field1Value", "field2Value"));
bloomFilter.add(new SomeObject("field5Value", "field8Value"));
bloomFilter.contains(new SomeObject("field1Value", "field8Value"));
6.8.1. 布隆過濾器數據分片(Sharding)
基於Redis的Redisson集群分布式布隆過濾器通過RClusteredBloomFilter接口,為集群狀態下的Redis環境提供了布隆過濾器數據分片的功能。 通過優化後更加有效的算法,通過壓縮未使用的比特比特來釋放集群內存空間。每個對象的狀態都將被分布在整個集群中。所含最大比特數量為2^64。在這裏可以獲取更多的內部信息。
RClusteredBloomFilter<SomeObject> bloomFilter = redisson.getClusteredBloomFilter("sample");
// 采用以下參數創建布隆過濾器
// expectedInsertions = 255000000
// falseProbability = 0.03
bloomFilter.tryInit(255000000L, 0.03);
bloomFilter.add(new SomeObject("field1Value", "field2Value"));
bloomFilter.add(new SomeObject("field5Value", "field8Value"));
bloomFilter.contains(new SomeObject("field1Value", "field8Value"));
該功能僅限於Redisson PRO版本。
6.9. 基數估計算法(HyperLogLog)
Redisson利用Redis實現了Java分布式基數估計算法(HyperLogLog)對象。該對象可以在有限的空間內通過概率算法統計大量的數據。除了同步接口外,還提供了异步(Async)、反射式(Reactive)和RxJava2標准的接口。
RHyperLogLog<Integer> log = redisson.getHyperLogLog("log");
log.add(1);
log.add(2);
log.add(3);
log.count();
6.10. 整長型累加器(LongAdder)
基於Redis的Redisson分布式整長型累加器(LongAdder)采用了與java.util.concurrent.atomic.LongAdder類似的接口。通過利用客戶端內置的LongAdder對象,為分布式環境下遞增和遞减操作提供了很高得性能。據統計其性能最高比分布式AtomicLong對象快 12000 倍。完美適用於分布式統計計量場景。
RLongAdder atomicLong = redisson.getLongAdder("myLongAdder");
atomicLong.add(12);
atomicLong.increment();
atomicLong.decrement();
atomicLong.sum();
當不再使用整長型累加器對象的時候應該自行手動銷毀,如果Redisson對象被關閉(shutdown)了,則不用手動銷毀。
RLongAdder atomicLong = ...
atomicLong.destroy();
6.11. 雙精度浮點累加器(DoubleAdder)
基於Redis的Redisson分布式雙精度浮點累加器(DoubleAdder)采用了與java.util.concurrent.atomic.DoubleAdder類似的接口。通過利用客戶端內置的DoubleAdder對象,為分布式環境下遞增和遞减操作提供了很高得性能。據統計其性能最高比分布式AtomicDouble對象快 12000 倍。完美適用於分布式統計計量場景。
RLongDouble atomicDouble = redisson.getLongDouble("myLongDouble");
atomicDouble.add(12);
atomicDouble.increment();
atomicDouble.decrement();
atomicDouble.sum();
當不再使用雙精度浮點累加器對象的時候應該自行手動銷毀,如果Redisson對象被關閉(shutdown)了,則不用手動銷毀。
RLongDouble atomicDouble = ...
_b6d2063_
atomicDouble.destroy();
6.12. 限流器(RateLimiter)
基於Redis的分布式限流器(RateLimiter)可以用來在分布式環境下現在請求方的調用頻率。既適用於不同Redisson實例下的多線程限流,也適用於相同Redisson實例下的多線程限流。該算法不保證公平性。除了同步接口外,還提供了异步(Async)、反射式(Reactive)和RxJava2標准的接口。
RRateLimiter rateLimiter = redisson.getRateLimiter("myRateLimiter");
// 初始化
// 最大流速 = 每1秒鐘產生10個令牌
rateLimiter.trySetRate(RateType.OVERALL, 10, 1, RateIntervalUnit.SECONDS);
CountDownLatch latch = new CountDownLatch(2);
limiter.acquire(3);
// ...
Thread t = new Thread(() -> {
limiter.acquire(2);
// ...
});
七、分布式集合
7.1. 映射(Map)
基於Redis的Redisson的分布式映射結構的RMap Java對象實現了java.util.concurrent.ConcurrentMap接口和java.util.Map接口。與HashMap不同的是,RMap保持了元素的插入順序。該對象的最大容量受Redis限制,最大元素數量是4 294 967 295個。
除了同步接口外,還提供了异步(Async)、反射式(Reactive)和RxJava2標准的接口。如果你想用Redis Map來保存你的POJO的話,可以考慮使用分布式實時對象(Live Object)服務。
在特定的場景下,映射緩存(Map)上的高度頻繁的讀取操作,使網絡通信都被視為瓶頸時,可以使用Redisson提供的帶有本地緩存功能的映射。
RMap<String, SomeObject> map = redisson.getMap("anyMap");
SomeObject prevObject = map.put("123", new SomeObject());
SomeObject currentObject = map.putIfAbsent("323", new SomeObject());
SomeObject obj = map.remove("123");
map.fastPut("321", new SomeObject());
map.fastRemove("321");
RFuture<SomeObject> putAsyncFuture = map.putAsync("321");
RFuture<Void> fastPutAsyncFuture = map.fastPutAsync("321");
map.fastPutAsync("321", new SomeObject());
map.fastRemoveAsync("321");
映射的字段鎖的用法:
RMap<MyKey, MyValue> map = redisson.getMap("anyMap");
MyKey k = new MyKey();
RLock keyLock = map.getLock(k);
keyLock.lock();
try {
MyValue v = map.get(k);
// 其他業務邏輯
} finally {
keyLock.unlock();
}
RReadWriteLock rwLock = map.getReadWriteLock(k);
rwLock.readLock().lock();
try {
MyValue v = map.get(k);
// 其他業務邏輯
} finally {
keyLock.readLock().unlock();
}
7.1.1. 映射(Map)的元素淘汰(Eviction),本地緩存(LocalCache)和數據分片(Sharding)
Redisson提供了一系列的映射類型的數據結構,這些結構按特性主要分為三大類:
元素淘汰(Eviction) 類 – 帶有元素淘汰(Eviction)機制的映射類允許針對一個映射中每個元素單獨設定 有效時間 和 最長閑置時間 。
本地緩存(LocalCache) 類 – 本地緩存(Local Cache)也叫就近緩存(Near Cache)。這類映射的使用主要用於在特定的場景下,映射緩存(MapCache)上的高度頻繁的讀取操作,使網絡通信都被視為瓶頸的情况。Redisson與Redis通信的同時,還將部分數據保存在本地內存裏。這樣的設計的好處是它能將讀取速度提高最多 45倍 。 所有同名的本地緩存共用一個訂閱發布話題,所有更新和過期消息都將通過該話題共享。
數據分片(Sharding) 類 – 數據分片(Sharding)類僅適用於Redis集群環境下,因此帶有數據分片(Sharding)功能的映射也叫集群分布式映射。它利用分庫的原理,將單一一個映射結構切分為若幹個小的映射,並均勻的分布在集群中的各個槽裏。這樣的設計能使一個單一映射結構突破Redis自身的容量限制,讓其容量隨集群的擴大而增長。在擴容的同時,還能够使讀寫性能和元素淘汰處理能力隨之成線性增長。
以下列錶是Redisson提供的所有映射的名稱及其特性:
除此以外,Redisson還提供了Spring Cache和JCache的實現。
元素淘汰功能(Eviction)
Redisson的分布式的RMapCache Java對象在基於RMap的前提下實現了針對單個元素的淘汰機制。同時仍然保留了元素的插入順序。由於RMapCache是基於RMap實現的,使它同時繼承了java.util.concurrent.ConcurrentMap接口和java.util.Map接口。Redisson提供的Spring Cache整合以及JCache正是基於這樣的功能來實現的。
目前的Redis自身並不支持散列(Hash)當中的元素淘汰,因此所有過期元素都是通過org.redisson.EvictionScheduler實例來實現定期清理的。為了保證資源的有效利用,每次運行最多清理300個過期元素。任務的啟動時間將根據上次實際清理數量自動調整,間隔時間趨於1秒到1小時之間。比如該次清理時删除了300條元素,那麼下次執行清理的時間將在1秒以後(最小間隔時間)。一旦該次清理數量少於上次清理數量,時間間隔將增加1.5倍。
RMapCache<String, SomeObject> map = redisson.getMapCache("anyMap");
// 有效時間 ttl = 10分鐘
map.put("key1", new SomeObject(), 10, TimeUnit.MINUTES);
// 有效時間 ttl = 10分鐘, 最長閑置時間 maxIdleTime = 10秒鐘
map.put("key1", new SomeObject(), 10, TimeUnit.MINUTES, 10, TimeUnit.SECONDS);
// 有效時間 = 3 秒鐘
map.putIfAbsent("key2", new SomeObject(), 3, TimeUnit.SECONDS);
// 有效時間 ttl = 40秒鐘, 最長閑置時間 maxIdleTime = 10秒鐘
map.putIfAbsent("key2", new SomeObject(), 40, TimeUnit.SECONDS, 10, TimeUnit.SECONDS);
本地緩存功能(Local Cache)
在特定的場景下,映射(Map)上的高度頻繁的讀取操作,使網絡通信都被視為瓶頸時,使用Redisson提供的帶有本地緩存功能的分布式本地緩存映射RLocalCachedMapJava對象會是一個很好的選擇。它同時實現了java.util.concurrent.ConcurrentMap和java.util.Map兩個接口。本地緩存功能充分的利用了JVM的自身內存空間,對部分常用的元素實行就地緩存,這樣的設計讓讀取操作的性能較分布式映射相比提高最多 45倍 。以下配置參數可以用來創建這個實例:
LocalCachedMapOptions options = LocalCachedMapOptions.defaults()
// 用於淘汰清除本地緩存內的元素
// 共有以下幾種選擇:
// LFU - 統計元素的使用頻率,淘汰用得最少(最不常用)的。
// LRU - 按元素使用時間排序比較,淘汰最早(最久遠)的。
// SOFT - 元素用Java的WeakReference來保存,緩存元素通過GC過程清除。
// WEAK - 元素用Java的SoftReference來保存, 緩存元素通過GC過程清除。
// NONE - 永不淘汰清除緩存元素。
.evictionPolicy(EvictionPolicy.NONE)
// 如果緩存容量值為0錶示不限制本地緩存容量大小
.cacheSize(1000)
// 以下選項適用於斷線原因造成了未收到本地緩存更新消息的情况。
// 斷線重連的策略有以下幾種:
// CLEAR - 如果斷線一段時間以後則在重新建立連接以後清空本地緩存
// LOAD - 在服務端保存一份10分鐘的作廢日志
// 如果10分鐘內重新建立連接,則按照作廢日志內的記錄清空本地緩存的元素
// 如果斷線時間超過了這個時間,則將清空本地緩存中所有的內容
// NONE - 默認值。斷線重連時不做處理。
.reconnectionStrategy(ReconnectionStrategy.NONE)
// 以下選項適用於不同本地緩存之間相互保持同步的情况
// 緩存同步策略有以下幾種:
// INVALIDATE - 默認值。當本地緩存映射的某條元素發生變動時,同時驅逐所有相同本地緩存映射內的該元素
// UPDATE - 當本地緩存映射的某條元素發生變動時,同時更新所有相同本地緩存映射內的該元素
// NONE - 不做任何同步處理
.syncStrategy(SyncStrategy.INVALIDATE)
// 每個Map本地緩存裏元素的有效時間,默認毫秒為單比特
.timeToLive(10000)
// 或者
.timeToLive(10, TimeUnit.SECONDS)
// 每個Map本地緩存裏元素的最長閑置時間,默認毫秒為單比特
.maxIdle(10000)
// 或者
.maxIdle(10, TimeUnit.SECONDS);
RLocalCachedMap<String, Integer> map = redisson.getLocalCachedMap("test", options);
String prevObject = map.put("123", 1);
String currentObject = map.putIfAbsent("323", 2);
String obj = map.remove("123");
// 在不需要舊值的情况下可以使用fast為前綴的類似方法
map.fastPut("a", 1);
map.fastPutIfAbsent("d", 32);
map.fastRemove("b");
RFuture<String> putAsyncFuture = map.putAsync("321");
RFuture<Void> fastPutAsyncFuture = map.fastPutAsync("321");
map.fastPutAsync("321", new SomeObject());
map.fastRemoveAsync("321");
當不再使用Map本地緩存對象的時候應該手動銷毀,如果Redisson對象被關閉(shutdown)了,則不用手動銷毀。
RLocalCachedMap<String, Integer> map = ...
map.destroy();
如何通過加載數據的方式來降低過期淘汰事件發布信息對網絡的影響
代碼範例:
public void loadData(String cacheName, Map<String, String> data) {
RLocalCachedMap<String, String> clearMap = redisson.getLocalCachedMap(cacheName,
LocalCachedMapOptions.defaults().cacheSize(1).syncStrategy(SyncStrategy.INVALIDATE));
RLocalCachedMap<String, String> loadMap = redisson.getLocalCachedMap(cacheName,
LocalCachedMapOptions.defaults().cacheSize(1).syncStrategy(SyncStrategy.NONE));
loadMap.putAll(data);
clearMap.clearLocalCache();
}
數據分片功能(Sharding)
Map數據分片是Redis集群模式下的一個功能。Redisson提供的分布式集群映射RClusteredMap Java對象也是基於RMap實現的。它同時實現了java.util.concurrent.ConcurrentMap和java.util.Map兩個接口。
RClusteredMap<String, SomeObject> map = redisson.getClusteredMap("anyMap");
SomeObject prevObject = map.put("123", new SomeObject());
SomeObject currentObject = map.putIfAbsent("323", new SomeObject());
SomeObject obj = map.remove("123");
map.fastPut("321", new SomeObject());
map.fastRemove("321");
7.1.2. 映射持久化方式(緩存策略)
Redisson供了將映射中的數據持久化到外部儲存服務的功能。主要場景有一下幾種:
- 將Redisson的分布式映射類型作為業務和外部儲存媒介之間的緩存。
- 或是用來增加Redisson映射類型中數據的持久性,或是用來增加已被驅逐的數據的壽命。
- 或是用來緩存數據庫,Web服務或其他數據源的數據。
Read-through策略
通俗的講,如果一個被請求的數據不存在於Redisson的映射中的時候,Redisson將通過預先配置好的MapLoader對象加載數據。
Write-through(數據同步寫入)策略
在遇到映射中某條數據被更改時,Redisson會首先通過預先配置好的MapWriter對象寫入到外部儲存系統,然後再更新Redis內的數據。
Write-behind(數據异步寫入)策略
對映射的數據的更改會首先寫入到Redis,然後再使用异步的方式,通過MapWriter對象寫入到外部儲存系統。在並發環境下可以通過writeBehindThreads參數來控制寫入線程的數量,已達到對外部儲存系統寫入並發量的控制。
以上策略適用於所有實現了RMap、RMapCache、RLocalCachedMap和RLocalCachedMapCache接口的對象。
配置範例:
MapOptions<K, V> options = MapOptions.<K, V>defaults()
.writer(myWriter)
.loader(myLoader);
RMap<K, V> map = redisson.getMap("test", options);
// 或
RMapCache<K, V> map = redisson.getMapCache("test", options);
// 或
RLocalCachedMap<K, V> map = redisson.getLocalCachedMap("test", options);
// 或
RLocalCachedMapCache<K, V> map = redisson.getLocalCachedMapCache("test", options);
7.1.3. 映射監聽器(Map Listener)
Redisson為所有實現了RMapCache或RLocalCachedMapCache接口的對象提供了監聽以下事件的監聽器:
事件 | 監聽器 元素 添加 事件 | org.redisson.api.map.event.EntryCreatedListener
元素 過期 事件 | org.redisson.api.map.event.EntryExpiredListener
元素 删除 事件 | org.redisson.api.map.event.EntryRemovedListener
元素 更新 事件 | org.redisson.api.map.event.EntryUpdatedListener
使用範例:
RMapCache<String, Integer> map = redisson.getMapCache("myMap");
// 或
RLocalCachedMapCache<String, Integer> map = redisson.getLocalCachedMapCache("myMap", options);
int updateListener = map.addListener(new EntryUpdatedListener<Integer, Integer>() {
@Override
public void onUpdated(EntryEvent<Integer, Integer> event) {
event.getKey(); // 字段名
event.getValue() // 新值
event.getOldValue() // 舊值
// ...
}
});
int createListener = map.addListener(new EntryCreatedListener<Integer, Integer>() {
@Override
public void onCreated(EntryEvent<Integer, Integer> event) {
event.getKey(); // 字段名
event.getValue() // 值
// ...
}
});
int expireListener = map.addListener(new EntryExpiredListener<Integer, Integer>() {
@Override
public void onExpired(EntryEvent<Integer, Integer> event) {
event.getKey(); // 字段名
event.getValue() // 值
// ...
}
});
int removeListener = map.addListener(new EntryRemovedListener<Integer, Integer>() {
@Override
public void onRemoved(EntryEvent<Integer, Integer> event) {
event.getKey(); // 字段名
event.getValue() // 值
// ...
}
});
map.removeListener(updateListener);
map.removeListener(createListener);
map.removeListener(expireListener);
map.removeListener(removeListener);
7.1.4. LRU有界映射
Redisson提供了基於Redis的以LRU為驅逐策略的分布式LRU有界映射對象。顧名思義,分布式LRU有界映射允許通過對其中元素按使用時間排序處理的方式,主動移除超過規定容量限制的元素。
RMapCache<String, String> map = redisson.getMapCache("map");
// 嘗試將該映射的最大容量限制設定為10
map.trySetMaxSize(10);
// 將該映射的最大容量限制設定或更改為10
map.setMaxSize(10);
map.put("1", "2");
map.put("3", "3", 1, TimeUnit.SECONDS);
7.2. 多值映射(Multimap)
基於Redis的Redisson的分布式RMultimap Java對象允許Map中的一個字段值包含多個元素。 字段總數受Redis限制,每個Multimap最多允許有4 294 967 295個不同字段。
7.2.1. 基於集(Set)的多值映射(Multimap)
基於Set的Multimap不允許一個字段值包含有重複的元素。
RSetMultimap<SimpleKey, SimpleValue> map = redisson.getSetMultimap("myMultimap");
map.put(new SimpleKey("0"), new SimpleValue("1"));
map.put(new SimpleKey("0"), new SimpleValue("2"));
map.put(new SimpleKey("3"), new SimpleValue("4"));
Set<SimpleValue> allValues = map.get(new SimpleKey("0"));
List<SimpleValue> newValues = Arrays.asList(new SimpleValue("7"), new SimpleValue("6"), new SimpleValue("5"));
Set<SimpleValue> oldValues = map.replaceValues(new SimpleKey("0"), newValues);
Set<SimpleValue> removedValues = map.removeAll(new SimpleKey("0"));
7.2.2. 基於列錶(List)的多值映射(Multimap)
基於List的Multimap在保持插入順序的同時允許一個字段下包含重複的元素。
RListMultimap<SimpleKey, SimpleValue> map = redisson.getListMultimap("test1");
map.put(new SimpleKey("0"), new SimpleValue("1"));
map.put(new SimpleKey("0"), new SimpleValue("2"));
map.put(new SimpleKey("0"), new SimpleValue("1"));
map.put(new SimpleKey("3"), new SimpleValue("4"));
List<SimpleValue> allValues = map.get(new SimpleKey("0"));
Collection<SimpleValue> newValues = Arrays.asList(new SimpleValue("7"), new SimpleValue("6"), new SimpleValue("5"));
List<SimpleValue> oldValues = map.replaceValues(new SimpleKey("0"), newValues);
List<SimpleValue> removedValues = map.removeAll(new SimpleKey("0"));
7.2.3. 多值映射(Multimap)淘汰機制(Eviction)
Multimap對象的淘汰機制是通過不同的接口來實現的。它們是RSetMultimapCache接口和RListMultimapCache接口,分別對應的是Set和List的Multimaps。
所有過期元素都是通過org.redisson.EvictionScheduler實例來實現定期清理的。為了保證資源的有效利用,每次運行最多清理100個過期元素。任務的啟動時間將根據上次實際清理數量自動調整,間隔時間趨於1秒到2小時之間。比如該次清理時删除了100條元素,那麼下次執行清理的時間將在1秒以後(最小間隔時間)。一旦該次清理數量少於上次清理數量,時間間隔將增加1.5倍。
RSetMultimapCache的使用範例:
RSetMultimapCache<String, String> multimap = redisson.getSetMultimapCache("myMultimap");
multimap.put("1", "a");
multimap.put("1", "b");
multimap.put("1", "c");
multimap.put("2", "e");
multimap.put("2", "f");
multimap.expireKey("2", 10, TimeUnit.MINUTES);
7.3. 集(Set)
基於Redis的Redisson的分布式Set結構的RSet Java對象實現了java.util.Set接口。通過元素的相互狀態比較保證了每個元素的唯一性。該對象的最大容量受Redis限制,最大元素數量是4 294 967 295個。
RSet<SomeObject> set = redisson.getSet("anySet");
set.add(new SomeObject());
set.remove(new SomeObject());
Redisson PRO版本中的Set對象還可以在Redis集群環境下支持單集合數據分片。
7.3.1. 集(Set)淘汰機制(Eviction)
基於Redis的Redisson的分布式RSetCache Java對象在基於RSet的前提下實現了針對單個元素的淘汰機制。由於RSetCache是基於RSet實現的,使它還集成了java.util.Set接口。
目前的Redis自身並不支持Set當中的元素淘汰,因此所有過期元素都是通過org.redisson.EvictionScheduler實例來實現定期清理的。為了保證資源的有效利用,每次運行最多清理100個過期元素。任務的啟動時間將根據上次實際清理數量自動調整,間隔時間趨於1秒到2小時之間。比如該次清理時删除了100條元素,那麼下次執行清理的時間將在1秒以後(最小間隔時間)。一旦該次清理數量少於上次清理數量,時間間隔將增加1.5倍。
RSetCache<SomeObject> set = redisson.getSetCache("anySet");
// ttl = 10 seconds
set.add(new SomeObject(), 10, TimeUnit.SECONDS);
7.3.2. 集(Set)數據分片(Sharding)
Set數據分片是Redis集群模式下的一個功能。Redisson提供的分布式RClusteredSet Java對象也是基於RSet實現的。在這裏可以獲取更多的信息。
RClusteredSet<SomeObject> set = redisson.getClusteredSet("anySet");
set.add(new SomeObject());
set.remove(new SomeObject());
除了RClusteredSet以外,Redisson還提供了另一種集群模式下的分布式集(Set),它不僅提供了透明的數據分片功能,還為每個元素提供了淘汰機制。RClusteredSetCache 類分別同時提供了RClusteredSet 和RSetCache 這兩個接口的實現。當然這些都是基於java.util.Set的接口實現上的。
該功能僅限於Redisson PRO版本。
7.4. 有序集(SortedSet)
基於Redis的Redisson的分布式RSortedSet Java對象實現了java.util.SortedSet接口。在保證元素唯一性的前提下,通過比較器(Comparator)接口實現了對元素的排序。
RSortedSet<Integer> set = redisson.getSortedSet("anySet");
set.trySetComparator(new MyComparator()); // 配置元素比較器
set.add(3);
set.add(1);
set.add(2);
set.removeAsync(0);
set.addAsync(5);
7.5. 計分排序集(ScoredSortedSet)
基於Redis的Redisson的分布式RScoredSortedSet Java對象是一個可以按插入時指定的元素評分排序的集合。它同時還保證了元素的唯一性。
RScoredSortedSet<SomeObject> set = redisson.getScoredSortedSet("simple");
set.add(0.13, new SomeObject(a, b));
set.addAsync(0.251, new SomeObject(c, d));
set.add(0.302, new SomeObject(g, d));
set.pollFirst();
set.pollLast();
int index = set.rank(new SomeObject(g, d)); // 獲取元素在集合中的比特置
Double score = set.getScore(new SomeObject(g, d)); // 獲取元素的評分
7.6. 字典排序集(LexSortedSet)
基於Redis的Redisson的分布式RLexSortedSet Java對象在實現了java.util.Set接口的同時,將其中的所有字符串元素按照字典順序排列。它公式還保證了字符串元素的唯一性。
RLexSortedSet set = redisson.getLexSortedSet("simple");
set.add("d");
set.addAsync("e");
set.add("f");
set.lexRangeTail("d", false);
set.lexCountHead("e");
set.lexRange("d", true, "z", false);
7.7. 列錶(List)
基於Redis的Redisson分布式列錶(List)結構的RList Java對象在實現了java.util.List接口的同時,確保了元素插入時的順序。該對象的最大容量受Redis限制,最大元素數量是4 294 967 295個。
RList<SomeObject> list = redisson.getList("anyList");
list.add(new SomeObject());
list.get(0);
list.remove(new SomeObject());
7.8. 隊列(Queue)
基於Redis的Redisson分布式無界隊列(Queue)結構的RQueue Java對象實現了java.util.Queue接口。盡管RQueue對象無初始大小(邊界)限制,但對象的最大容量受Redis限制,最大元素數量是4 294 967 295個。
RQueue<SomeObject> queue = redisson.getQueue("anyQueue");
queue.add(new SomeObject());
SomeObject obj = queue.peek();
SomeObject someObj = queue.poll();
7.9. 雙端隊列(Deque)
基於Redis的Redisson分布式無界雙端隊列(Deque)結構的RDeque Java對象實現了java.util.Deque接口。盡管RDeque對象無初始大小(邊界)限制,但對象的最大容量受Redis限制,最大元素數量是4 294 967 295個。
RDeque<SomeObject> queue = redisson.getDeque("anyDeque");
queue.addFirst(new SomeObject());
queue.addLast(new SomeObject());
SomeObject obj = queue.removeFirst();
SomeObject someObj = queue.removeLast();
7.10. 阻塞隊列(Blocking Queue)
基於Redis的Redisson分布式無界阻塞隊列(Blocking Queue)結構的RBlockingQueue Java對象實現了java.util.concurrent.BlockingQueue接口。盡管RBlockingQueue對象無初始大小(邊界)限制,但對象的最大容量受Redis限制,最大元素數量是4 294 967 295個。
RBlockingQueue<SomeObject> queue = redisson.getBlockingQueue("anyQueue");
queue.offer(new SomeObject());
SomeObject obj = queue.peek();
SomeObject someObj = queue.poll();
SomeObject ob = queue.poll(10, TimeUnit.MINUTES);
poll, pollFromAny, pollLastAndOfferFirstTo和take方法內部采用話題訂閱發布實現,在Redis節點故障轉移(主從切換)或斷線重連以後,內置的相關話題監聽器將自動完成話題的重新訂閱。
7.11. 有界阻塞隊列(Bounded Blocking Queue)
基於Redis的Redisson分布式有界阻塞隊列(Bounded Blocking Queue)結構的RBoundedBlockingQueue Java對象實現了java.util.concurrent.BlockingQueue接口。該對象的最大容量受Redis限制,最大元素數量是4 294 967 295個。隊列的初始容量(邊界)必須在使用前設定好。
RBoundedBlockingQueue<SomeObject> queue = redisson.getBoundedBlockingQueue("anyQueue");
// 如果初始容量(邊界)設定成功則返回`真(true)`,
// 如果初始容量(邊界)已近存在則返回`假(false)`。
queue.trySetCapacity(2);
queue.offer(new SomeObject(1));
queue.offer(new SomeObject(2));
// 此時容量已滿,下面代碼將會被阻塞,直到有空閑為止。
queue.put(new SomeObject());
SomeObject obj = queue.peek();
SomeObject someObj = queue.poll();
SomeObject ob = queue.poll(10, TimeUnit.MINUTES);
poll, pollFromAny, pollLastAndOfferFirstTo和take方法內部采用話題訂閱發布實現,在Redis節點故障轉移(主從切換)或斷線重連以後,內置的相關話題監聽器將自動完成話題的重新訂閱。
7.12. 阻塞雙端隊列(Blocking Deque)
基於Redis的Redisson分布式無界阻塞雙端隊列(Blocking Deque)結構的RBlockingDeque Java對象實現了java.util.concurrent.BlockingDeque接口。盡管RBlockingDeque對象無初始大小(邊界)限制,但對象的最大容量受Redis限制,最大元素數量是4 294 967 295個。
RBlockingDeque<Integer> deque = redisson.getBlockingDeque("anyDeque");
deque.putFirst(1);
deque.putLast(2);
Integer firstValue = queue.takeFirst();
Integer lastValue = queue.takeLast();
Integer firstValue = queue.pollFirst(10, TimeUnit.MINUTES);
Integer lastValue = queue.pollLast(3, TimeUnit.MINUTES);
poll, pollFromAny, pollLastAndOfferFirstTo和take方法內部采用話題訂閱發布實現,在Redis節點故障轉移(主從切換)或斷線重連以後,內置的相關話題監聽器將自動完成話題的重新訂閱。
7.13. 阻塞公平隊列(Blocking Fair Queue)
基於Redis的Redisson分布式無界阻塞公平隊列(Blocking Fair Queue)結構的RBlockingFairQueue Java對象在實現Redisson分布式無界阻塞隊列(Blocking Queue)結構RBlockingQueue接口的基礎上,解决了多個隊列消息的處理者在複雜的網絡環境下,網絡延時的影響使“較遠”的客戶端最終收到消息數量低於“較近”的客戶端的問題。從而解决了這種現象引發的個別處理節點過載的情况。
以分布式無界阻塞隊列為基礎,采用公平獲取消息的機制,不僅保證了poll、pollFromAny、pollLastAndOfferFirstTo和take方法獲取消息的先入順序,還能讓隊列裏的消息被均勻的發布到處在複雜分布式環境中的各個處理節點裏。
RBlockingFairQueue queue = redisson.getBlockingFairQueue("myQueue");
queue.offer(new SomeObject());
SomeObject obj = queue.peek();
SomeObject someObj = queue.poll();
SomeObject ob = queue.poll(10, TimeUnit.MINUTES);
該功能僅限於Redisson PRO版本。
7.14. 阻塞公平雙端隊列(Blocking Fair Deque)
基於Redis的Redisson分布式無界阻塞公平雙端隊列(Blocking Fair Deque)結構的RBlockingFairDeque Java對象在實現Redisson分布式無界阻塞雙端隊列(Blocking Deque)結構RBlockingDeque接口的基礎上,解决了多個隊列消息的處理者在複雜的網絡環境下,網絡延時的影響使“較遠”的客戶端最終收到消息數量低於“較近”的客戶端的問題。從而解决了這種現象引發的個別處理節點過載的情况。
以分布式無界阻塞雙端隊列為基礎,采用公平獲取消息的機制,不僅保證了poll、take、pollFirst、takeFirst、pollLast和takeLast方法獲取消息的先入順序,還能讓隊列裏的消息被均勻的發布到處在複雜分布式環境中的各個處理節點裏。
RBlockingFairDeque deque = redisson.getBlockingFairDeque("myDeque");
deque.offer(new SomeObject());
SomeObject firstElement = queue.peekFirst();
SomeObject firstElement = queue.pollFirst();
SomeObject firstElement = queue.pollFirst(10, TimeUnit.MINUTES);
SomeObject firstElement = queue.takeFirst();
SomeObject lastElement = queue.peekLast();
SomeObject lastElement = queue.pollLast();
SomeObject lastElement = queue.pollLast(10, TimeUnit.MINUTES);
SomeObject lastElement = queue.takeLast();
該功能僅限於Redisson PRO版本。
7.15. 延遲隊列(Delayed Queue)
基於Redis的Redisson分布式延遲隊列(Delayed Queue)結構的RDelayedQueue Java對象在實現了RQueue接口的基礎上提供了向隊列按要求延遲添加項目的功能。該功能可以用來實現消息傳送延遲按幾何增長或幾何衰减的發送策略。
RQueue<String> distinationQueue = ...
RDelayedQueue<String> delayedQueue = getDelayedQueue(distinationQueue);
// 10秒鐘以後將消息發送到指定隊列
delayedQueue.offer("msg1", 10, TimeUnit.SECONDS);
// 一分鐘以後將消息發送到指定隊列
delayedQueue.offer("msg2", 1, TimeUnit.MINUTES);
在該對象不再需要的情况下,應該主動銷毀。僅在相關的Redisson對象也需要關閉的時候可以不用主動銷毀。
RDelayedQueue<String> delayedQueue = ...
delayedQueue.destroy();
7.16. 優先隊列(Priority Queue)
基於Redis的Redisson分布式優先隊列(Priority Queue)Java對象實現了java.util.Queue的接口。可以通過比較器(Comparator)接口來對元素排序。
RPriorityQueue<Integer> queue = redisson.getPriorityQueue("anyQueue");
queue.trySetComparator(new MyComparator()); // 指定對象比較器
queue.add(3);
queue.add(1);
queue.add(2);
queue.removeAsync(0);
queue.addAsync(5);
queue.poll();
7.17. 優先雙端隊列(Priority Deque)
基於Redis的Redisson分布式優先雙端隊列(Priority Deque)Java對象實現了java.util.Deque的接口。可以通過比較器(Comparator)接口來對元素排序。
RPriorityDeque<Integer> queue = redisson.getPriorityDeque("anyQueue");
queue.trySetComparator(new MyComparator()); // 指定對象比較器
queue.addLast(3);
queue.addFirst(1);
queue.add(2);
queue.removeAsync(0);
queue.addAsync(5);
queue.pollFirst();
queue.pollLast();
7.18. 優先阻塞隊列(Priority Blocking Queue)
基於Redis的分布式無界優先阻塞隊列(Priority Blocking Queue)Java對象的結構與java.util.concurrent.PriorityBlockingQueue類似。可以通過比較器(Comparator)接口來對元素排序。PriorityBlockingQueue的最大容量是4 294 967 295個元素。
RPriorityBlockingQueue<Integer> queue = redisson.getPriorityBlockingQueue("anyQueue");
queue.trySetComparator(new MyComparator()); // 指定對象比較器
queue.add(3);
queue.add(1);
queue.add(2);
queue.removeAsync(0);
queue.addAsync(5);
queue.take();
當Redis服務端斷線重連以後,或Redis服務端發生主從切換,並重新建立連接後,斷線時正在使用poll,pollLastAndOfferFirstTo或take方法的對象Redisson將自動再次為其訂閱相關的話題。
7.19. 優先阻塞雙端隊列(Priority Blocking Deque)
基於Redis的分布式無界優先阻塞雙端隊列(Priority Blocking Deque)Java對象實現了java.util.Deque的接口。addLast、 addFirst、push方法不能再這個對裏使用。PriorityBlockingDeque的最大容量是4 294 967 295個元素。
RPriorityBlockingDeque<Integer> queue = redisson.getPriorityBlockingDeque("anyQueue");
queue.trySetComparator(new MyComparator()); // 指定對象比較器
queue.add(2);
queue.removeAsync(0);
queue.addAsync(5);
queue.pollFirst();
queue.pollLast();
queue.takeFirst();
queue.takeLast();
當Redis服務端斷線重連以後,或Redis服務端發生主從切換,並重新建立連接後,斷線時正在使用poll,pollLastAndOfferFirstTo或take方法的對象Redisson將自動再次為其訂閱相關的話題。
边栏推荐
- 【推荐系统】美团外卖推荐场景的深度位置交互网络DPIN的突破与畅想
- ctfshow-web354(SSRF)
- 【Flutter 问题系列第 72 篇】在 Flutter 中使用 Camera 插件拍的图片被拉伸问题的解决方案
- 1286_ Implementation analysis of task priority setting in FreeRTOS
- Will Internet talents be scarce in the future? Which technology directions are popular?
- [lingo] solve quadratic programming
- LeetCode+ 71 - 75
- 华为ModelArts训练Alexnet模型
- How to permanently configure local opencv4.5.5 for vs2019
- Operation and maintenance management system, humanized operation experience
猜你喜欢
[lingo] solve quadratic programming
Will Internet talents be scarce in the future? Which technology directions are popular?
[Electrical dielectric number] electrical dielectric number and calculation considering HVDC and facts components
How to permanently configure local opencv4.5.5 for vs2019
【LINGO】求七个城市最小连线图,使天然气管道价格最低
Understanding of Turing test and Chinese Room
【MATLAB】求解非线性规划
How to create an exclusive vs Code theme
Système de gestion de l'exploitation et de l'entretien, expérience d'exploitation humanisée
【LINGO】求无向图的最短路问题
随机推荐
电脑有网络,但所有浏览器网页都打不开,是怎么回事?
用手机在指南针上开户靠谱吗?这样有没有什么安全隐患
C language implementation [Sanzi chess game] (step analysis and implementation source code)
关于图灵测试和中文屋Chinese room的理解
Chinese explanation of common rclone subcommands
rclone 访问web界面
Product learning (III) - demand list
[lingo] find the shortest path problem of undirected graph
Which securities company is better or safer for mobile phone account opening
Solution to the problem that objects in unity2021 scene view cannot be directly selected
[recommendation technology] matlab simulation of network information recommendation technology based on collaborative filtering
How to enter the Internet industry and become a product manager? How to become a product manager without project experience?
Is the account opening of GF Securities safe and reliable? How to open GF Securities Account
[matlab] solve nonlinear programming
[Tikhonov] image super-resolution reconstruction based on Tikhonov regularization
熱烈祝賀五行和合酒成功掛牌
【推荐技术】基于协同过滤的网络信息推荐技术matlab仿真
【分类模型】Q 型聚类分析
[target detection] yolov5, the shoulder of target detection (detailed principle + Training Guide)
华泰证券开户是安全可靠的么?怎么开华泰证券账户