Redis都要老了,你還在用什么古董客戶端?
本文轉(zhuǎn)載自微信公眾號「小姐姐味道」,作者小姐姐養(yǎng)的狗。轉(zhuǎn)載本文請聯(lián)系小姐姐味道公眾號。
前幾日,Redis 創(chuàng)始人 Antirez 在他的個人博客上宣布將結(jié)束自己的 Redis 之旅!
大神累了,Redis老了,但Redis依舊很火。
Redis的Java客戶端有很多,比如jedis、redisson、lettuce等。
那大家都在用啥呢?
今天xjjdog做了一個小調(diào)查。下面是統(tǒng)計結(jié)果。
可以看到j(luò)edis以絕對的優(yōu)勢占據(jù)了榜首。
下面簡單的分析一小下。
jedis
jedis和redis只相差1個字母。我通常把它叫做redis和Java的合體。它有以下特點:
- 非常的輕量級、簡潔,非常方便進行改造和集成
 - 支持單機、哨兵、Cluster等部署模式,支持事務(wù)、pipeline、LUA腳本等。功能齊全。
 - 不支持讀寫分離,需要自己實現(xiàn)
 - 使用了BIO模型,方法調(diào)用是同步的
 - 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
我通常把它叫做redis的兒子。由于是兒子,所以有些功能并不支持。
- 提供分布式鎖等常見的操作封裝,并實現(xiàn)了分布式和可擴展的Java數(shù)據(jù)結(jié)構(gòu),但不支持一些基礎(chǔ)的Redis原生功能
 - 基于Netty實現(xiàn),采用非阻塞IO,性能高。支持異步的請求
 - 不支持事務(wù)操作,可以使用LUA腳本實現(xiàn)
 - 支持在主從部署和cluster部署模式下的讀寫分離。在此基礎(chǔ)上,支持讀操作負(fù)載均衡
 - api是線程安全的,單個連接可以完成多個操作
 - 可以與Spring Session集成實現(xiàn)會話共享
 - 支持連接池
 - 有中文文檔 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
生菜的意思,應(yīng)該是圖騰,因為和我想不起和redis的任何聯(lián)系。
- 基于Netty框架的事件驅(qū)動的通信層,方法調(diào)用也是異步的
 - 不需要考慮線程池,性能比較高,Spring生態(tài)默認(rèn)
 - 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,但是還得靠注釋來明白這段代碼是干啥的。但同時帶來的好處就是可塑性強,可以根據(jù)自己的需求把它扭成合適的樣子。另外,jedis還是BIO的,雖然BIO一般來說都比較慢,但是redis本身就是很快的,不會阻塞很久,這個在普通項目里并沒有什么大的問題。
redisson進行了更高級的封裝,功能單一,但可以讓使用者將精力更集中供暖的放在業(yè)務(wù)邏輯上 ,封裝了很多的輪子。Redisson不僅提供了一系列的分布式Java常用對象,基本可以與Java的基本數(shù)據(jù)結(jié)構(gòu)通用,還擴展了許多分布式數(shù)據(jù)結(jié)構(gòu),其中包括(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,速度上自然就快一點。我還是通過它實現(xiàn)的一些高級api上知道的它,最著名的就是它的分布式鎖,可以像使用Java的可重入鎖一樣使用它。
Lettuce是生菜的意思,也是Spring的RedisTemplate現(xiàn)在默認(rèn)的底層實現(xiàn)。比起jedis需要為每個實例創(chuàng)建物理連接來保證線程安全,lettuce確實很優(yōu)秀。它的性能比較高,支持異步。性能雖然高,但是編程模型比較復(fù)雜,不太直觀,很多人不太喜歡。
目前來看,大多數(shù)項目還在用著BIO的jedis,這沒什么問題。jedis的功能齊全,api比較初級好定制,性能也能滿足需求。更重要的是,它先入為主,已經(jīng)成了很多人的標(biāo)配。
如果在功能上、性能上,已經(jīng)滿足需求,那又有什么理由去換一個新的呢?是閑的蛋疼么?
羞刀難入鞘,傲劍不回鋒 ?不存在的。
如果有了Spring封裝的這一層,屏蔽了這些蛋疼的切換操作,又有什么理由不換一個快的呢?
作者簡介:小姐姐味道 (xjjdog),一個不允許程序員走彎路的公眾號。聚焦基礎(chǔ)架構(gòu)和Linux。十年架構(gòu),日百億流量,與你探討高并發(fā)世界,給你不一樣的味道。



















 
 
 






 
 
 
 