Redis都要老了,你還在用什麼古董客戶端?
前幾日,Redis 創始人 Antirez 在他的個人部落格上宣佈將結束自己的 Redis 之旅!
大神累了,Redis老了,但Redis依舊很火。
Redis的Java客戶端有很多,比如jedis、redisson、lettuce等。
那大家都在用啥呢?
今天xjjdog做了一個小調查。下面是統計結果。 localfile://media/15940259145555/15940262979977.jpg
可以看到jedis以絕對的優勢佔據了榜首。
下面簡單的分析一小下。
jedis
localfile://media/15940259145555/15940301796032.jpg
jedis和redis只相差1個字母。我通常把它叫做
- 非常的輕量級、簡潔,非常方便進行改造和整合
- 支援單機、哨兵、Cluster等部署模式,支援事務、pipeline、LUA指令碼等。功能齊全。
- 不支援讀寫分離,需要自己實現
- 使用了BIO模型,方法呼叫是同步的
- jedis客戶端例項不是執行緒安全的,需要使用連線池來使用
- 支援連線池
程式碼樣例。
Jedis jedis = null;
try {
jedis = pool.getResource();
/// ... do stuff here ... for example
jedis.set("foo", "bar");
String foobar = jedis.get("foo");
jedis.zadd("sose", 0, "car"); jedis.zadd("sose", 0, "bike");
Set<String> sose = jedis.zrange("sose", 0, -1);
} finally {
// You have to close jedis object. If you don't close then
// it doesn't release back to pool and you can't get a new
// resource from pool.
if (jedis != null) {
jedis.close();
}
}
/// ... when closing your application:
pool.close();
複製程式碼
redisson
localfile://media/15940259145555/15940302787489.jpg
我通常把它叫做redis的兒子。由於是兒子,所以有些功能並不支援。
- 提供
分散式鎖
等常見的操作封裝,並實現了分散式和可擴充套件的Java資料結構,但不支援一些基礎的Redis原生功能 - 基於Netty實現,採用非阻塞IO,效能高。支援非同步的請求
- 不支援事務操作,可以使用LUA指令碼實現
- 支援在主從部署和cluster部署模式下的讀寫分離。在此基礎上,支援讀操作負載均衡
- api是執行緒安全的,單個連線可以完成多個操作
- 可以與Spring Session整合實現會話共享
- 支援連線池
- 有中文文件 O__O
程式碼樣例。
// 1. Create config object
Config config = new Config();
config.useClusterServers()
// use "rediss://" for SSL connection
.addNodeAddress("redis://127.0.0.1:7181");
// or read config from file
config = Config.fromYAML(new File("config-file.yaml"));
// 2. Create Redisson instance
// Sync and Async API
RedissonClient redisson = Redisson.create(config);
// RxJava2 API
RedissonRxClient redissonRx = Redisson.createRx(config);
// 3. Get Redis based Map
RMap<MyKey, MyValue> map = redisson.getMap("myMap");
RMapReactive<MyKey, MyValue> mapReactive = redissonReactive.getMap("myMap");
RMapRx<MyKey, MyValue> mapRx = redissonRx.getMap("myMap");
// 4. Get Redis based Lock
RLock lock = redisson.getLock("myLock");
RLockReactive lockReactive = redissonReactive.getLock("myLock");
RLockRx lockRx = redissonRx.getLock("myLock");
複製程式碼
Lettuce
生菜的意思,應該是圖騰,因為和我想不起和redis的任何聯絡。 localfile://media/15940259145555/15940301291245.jpg
- 基於Netty框架的事件驅動的通訊層,方法呼叫也是非同步的
- 不需要考慮執行緒池,效能比較高,Spring生態預設
- api是執行緒安全的,單個連線可以完成多個操作
- 同樣支援連線池
程式碼案例。
RedisClient client = RedisClient.create("redis://localhost");
StatefulRedisConnection<String, String> connection = client.connect();
RedisStringCommands sync = connection.sync();
String value = sync.get("key");
////////////////////
StatefulRedisConnection<String, String> connection = client.connect();
RedisStringAsyncCommands<String, String> async = connection.async();
RedisFuture<String> set = async.set("key", "value")
RedisFuture<String> get = async.get("key")
async.awaitAll(set, get) == true
set.get() == "OK"
get.get() == "value"
複製程式碼
小小分析
jedis支援最原生的操作,什麼都能幹,但是它的表達語義是有限的,可能寫了一堆getset,但是還得靠註釋來明白這段程式碼是幹啥的。但同時帶來的好處就是可塑性強,可以根據自己的需求把它扭成合適的樣子。另外,jedis還是BIO的,雖然BIO一般來說都比較慢,但是redis本身就是很快的,不會阻塞很久,這個在普通專案裡並沒有什麼大的問題。
redisson進行了更高階的封裝,功能單一,但可以讓使用者將精力更集中供暖的放在業務邏輯上 ,封裝了很多的輪子。Redisson不僅提供了一系列的分散式Java常用物件,基本可以與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)。它基於Netty,支援NIO,速度上自然就快一點。我還是通過它實現的一些高階api上知道的它,最著名的就是它的分散式鎖,可以像使用Java的可重入鎖一樣使用它。
Lettuce是生菜的意思,也是Spring的RedisTemplate現在預設的底層實現。比起jedis需要為每個例項建立物理連線來保證執行緒安全,lettuce確實很優秀。它的效能比較高,支援非同步。效能雖然高,但是程式設計模型比較複雜,不太直觀,很多人不太喜歡。
目前來看,大多數專案還在用著BIO的jedis,這沒什麼問題。jedis的功能齊全,api比較初級好定製,效能也能滿足需求。更重要的是,它先入為主,已經成了很多人的標配。
如果在功能上、效能上,已經滿足需求,那又有什麼理由去換一個新的呢?是閒的蛋疼麼?
羞刀難入鞘,傲劍不回鋒 ?不存在的。
如果有了Spring封裝的這一層,遮蔽了這些蛋疼的切換操作,又有什麼理由不換一個快的呢?