jedis操作redis的幾種方式
redis是一個著名的key-value儲存系統,也是nosql中的最常見的一種。其實,個人認為,redis最強大的地方不在於其儲存,而在於其強大的快取作用。
我們可以把它想象成一個巨大的(多借點叢集,聚合多借點的記憶體)的Map,也就是Key-Value。
所以,我們可以把它做成快取元件。
官方推薦的java版客戶端是jedis,非常強大和穩定,支援事務、管道及有jedis自身實現。我們對redis資料的操作,都可以通過jedis來完成。
那我們就來看一看,jedis不同的呼叫方式:
(1)普通同步方式
這是一種最簡單和最基礎的呼叫方式,對於簡單的資料存取需求,我們可以通過這種方式呼叫。
public void jedisNormal() { Jedis jedis = new Jedis("localhost"); long start = System.currentTimeMillis(); for (int i = 0; i < 100000; i++) { String result = jedis.set("n" + i, "n" + i); } long end = System.currentTimeMillis(); System.out.println("Simple SET: " + ((end - start)/1000.0) + " seconds"); jedis.disconnect(); } //每次set之後都可以返回結果,標記是否成功。
(2)事務方式(Transactions)
所謂事務,即一個連續操作,是否執行是一個事務,要麼完成,要麼失敗,沒有中間狀態。
而redis的事務很簡單,他主要目的是保障,一個client發起的事務中的命令可以連續的執行,而中間不會插入其他client的命令,也就是事務的連貫性。
public void jedisTrans() { Jedis jedis = new Jedis("localhost"); long start = System.currentTimeMillis(); Transaction tx = jedis.multi(); for (int i = 0; i < 100000; i++) { tx.set("t" + i, "t" + i); } List<Object> results = tx.exec(); long end = System.currentTimeMillis(); System.out.println("Transaction SET: " + ((end - start)/1000.0) + " seconds"); jedis.disconnect(); } //我們呼叫jedis.watch(…)方法來監控key,如果呼叫後key值發生變化,則整個事務會執行失敗。另外,事務中某個操作失敗,並不會回滾其他操作。這一點需要注意。還有,我們可以使用discard()方法來取消事務。
(3)管道(Pipelining)
管道是一種兩個程序之間單向通訊的機制。
那再redis中,為何要使用管道呢?有時候,我們需要採用非同步的方式,一次傳送多個指令,並且,不同步等待其返回結果。這樣可以取得非常好的執行效率。
public void jedisPipelined() {
Jedis jedis = new Jedis("localhost");
Pipeline pipeline = jedis.pipelined();
long start = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
pipeline.set("p" + i, "p" + i);
}
List<Object> results = pipeline.syncAndReturnAll();
long end = System.currentTimeMillis();
System.out.println("Pipelined SET: " + ((end - start)/1000.0) + " seconds");
jedis.disconnect();
}
(4)管道中呼叫事務
對於,事務以及管道,這兩個概念我們都清楚了。
在某種需求下,我們需要非同步執行命令,但是,又希望多個命令是有連續的,所以,我們就採用管道加事務的呼叫方式。jedis是支援在管道中呼叫事務的。
public void jedisCombPipelineTrans() {
jedis = new Jedis("localhost");
long start = System.currentTimeMillis();
Pipeline pipeline = jedis.pipelined();
pipeline.multi();
for (int i = 0; i < 100000; i++) {
pipeline.set("" + i, "" + i);
}
pipeline.exec();
List<Object> results = pipeline.syncAndReturnAll();
long end = System.currentTimeMillis();
System.out.println("Pipelined transaction: " + ((end - start)/1000.0) + " seconds");
jedis.disconnect();
}
//效率上可能會有所欠缺
(5)分散式直連同步呼叫
這個是分散式直接連線,並且是同步呼叫,每步執行都返回執行結果。類似地,還有非同步管道呼叫。
其實就是分片。
public void jedisShardNormal() {
List<JedisShardInfo> shards = Arrays.asList(
new JedisShardInfo("localhost",6379),
new JedisShardInfo("localhost",6380));
ShardedJedis sharding = new ShardedJedis(shards);
long start = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
String result = sharding.set("sn" + i, "n" + i);
}
long end = System.currentTimeMillis();
System.out.println("[email protected] SET: " + ((end - start)/1000.0) + " seconds");
sharding.disconnect();
}
(6)分散式直連非同步呼叫
public void jedisShardpipelined() {
List<JedisShardInfo> shards = Arrays.asList(
new JedisShardInfo("localhost",6379),
new JedisShardInfo("localhost",6380));
ShardedJedis sharding = new ShardedJedis(shards);
ShardedJedisPipeline pipeline = sharding.pipelined();
long start = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
pipeline.set("sp" + i, "p" + i);
}
List<Object> results = pipeline.syncAndReturnAll();
long end = System.currentTimeMillis();
System.out.println("[email protected] SET: " + ((end - start)/1000.0) + " seconds");
sharding.disconnect();
}
(7)分散式連線池同步呼叫
如果,你的分散式呼叫程式碼是執行線上程中,那麼上面兩個直連呼叫方式就不合適了,因為直連方式是非執行緒安全的,這個時候,你就必須選擇連線池呼叫。
連線池的呼叫方式,適合大規模的redis叢集,並且多客戶端的操作。
public void jedisShardSimplePool() {
List<JedisShardInfo> shards = Arrays.asList(
new JedisShardInfo("localhost",6379),
new JedisShardInfo("localhost",6380));
ShardedJedisPool pool = new ShardedJedisPool(new JedisPoolConfig(), shards);
ShardedJedis one = pool.getResource();
long start = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
String result = one.set("spn" + i, "n" + i);
}
long end = System.currentTimeMillis();
pool.returnResource(one);
System.out.println("[email protected] SET: " + ((end - start)/1000.0) + " seconds");
pool.destroy();
}
(8)分散式連線池非同步呼叫
public void jedisShardPipelinedPool() {
List<JedisShardInfo> shards = Arrays.asList(
new JedisShardInfo("localhost",6379),
new JedisShardInfo("localhost",6380));
ShardedJedisPool pool = new ShardedJedisPool(new JedisPoolConfig(), shards);
ShardedJedis one = pool.getResource();
ShardedJedisPipeline pipeline = one.pipelined();
long start = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
pipeline.set("sppn" + i, "n" + i);
}
List<Object> results = pipeline.syncAndReturnAll();
long end = System.currentTimeMillis();
pool.returnResource(one);
System.out.println("[email protected] SET: " + ((end - start)/1000.0) + " seconds");
pool.destroy();
}
(9)需要注意的地方
-
事務和管道都是非同步模式。在事務和管道中不能同步查詢結果。比如下面兩個呼叫,都是不允許的:
-
Transaction tx = jedis.multi(); for (int i = 0; i < 100000; i++) { tx.set("t" + i, "t" + i); } System.out.println(tx.get("t1000").get()); //不允許 List<Object> results = tx.exec(); … … Pipeline pipeline = jedis.pipelined(); long start = System.currentTimeMillis(); for (int i = 0; i < 100000; i++) { pipeline.set("p" + i, "p" + i); } System.out.println(pipeline.get("p1000").get()); //不允許 List<Object> results = pipeline.syncAndReturnAll();
-
事務和管道都是非同步的,個人感覺,在管道中再進行事務呼叫,沒有必要,不如直接進行事務模式。
-
分散式中,連線池的效能比直連的效能略好(見後續測試部分)。
-
分散式呼叫中不支援事務。
-
因為事務是在伺服器端實現,而在分散式中,每批次的呼叫物件都可能訪問不同的機器,所以,沒法進行事務。
(10)總結
-
分散式中,連線池方式呼叫不但執行緒安全外,根據上面的測試資料,也可以看出連線池比直連的效率更好。
-
經測試分散式中用到的機器越多,呼叫會越慢。
相關推薦
Java的jdbc使用addBatch進行批處理操作的幾種方式
方式一、批量執行預定義模式的SQL public static void exeBatch(Connection conn) { try { String sql = "insert into t_example (code, name) values (?,?)";
日期格式化操作的幾種方式
由於DateFormat是非執行緒安全的,因此在多執行緒併發情況下日期格式化時需要特別注意。執行緒不安全的處理方式private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH
Android隨筆之——模擬按鍵操作的幾種方式
1 package com.lsj.keyboardsample; 2 3 import android.app.Activity; 4 import android.app.Instrumentation; 5 import android.os.Bundle; 6 import andro
C#執行非同步操作的幾種方式比較和總結
原文地址:http://www.cnblogs.com/durow/p/4826653.html 轉載此文的目的就是想讓自己記住曾經尋找過這些資料 感謝這位博主的無私奉獻 0x00 引言 之前寫程式的時候在遇到一些比較花時間的操作例如HTTP請求時,總是會new一
jedis操作redis的幾種方式
redis是一個著名的key-value儲存系統,也是nosql中的最常見的一種。其實,個人認為,redis最強大的地方不在於其儲存,而在於其強大的快取作用。 我們可以把它想象成一個巨大的(多借點叢集,聚合多借點的記憶體)的Map,也就是Key-Value。 所以,我
彈窗確認操作的業務邏輯與幾種方式
back confirm function 綁定 問題 tor asc all document 首先,我是一名菜雞的前端開發工程師,只會切圖,除開切圖之外 我只有兩個不會,這也不會,那也不會。 最近在做一個後臺管理的項目,我需要做一個功能: 在後臺操作 刪除 修改
redis持久化的幾種方式
但是 工作 http 計算 targe pen 化工 index 數據安全 Redis是一種高級key-value數據庫。它跟memcached類似,不過數據可以持久化,而且支持的數據類型很豐富。有字符串,鏈表,集 合和有序集合。支持在服務器端計算集合的並,交和補集(d
WPFの操作檔案瀏覽框幾種方式
原文: WPFの操作檔案瀏覽框幾種方式 方式1: 使用win32控制元件OpenFileDialog Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog(); ofd.DefaultExt
Redis持久化策略(RDB &AOF) redis持久化的幾種方式 1、前言
redis持久化的幾種方式 1、前言 Redis是一種高階key-value資料庫。它跟memcached類似,不過資料可以持久化,而且支援的資料型別很豐富。有字串,連結串列,集 合和有序集合。支援在伺服器端計算集合的並,交和補集(difference)等,還支援多種
[Redis] Redis叢集的幾種方式
專案中用到Redis,所以準備學習一下,感覺Redis的概念還是很多的,什麼主從模式、sentinel模式、叢集模式的,一下子都暈了,我覺得還是有必要先理清這些基本概念再說。 一、單節點例項 單節點例項還是比較簡單的,平時做個測試,寫個小程式如果需要用到快取的話,啟
redis持久化幾種方式的比較
redis持久化的幾種方式 1、前言 Redis是一種高階key-value資料庫。它跟memcached類似,不過資料可以持久化,而且支援的資料型別很豐富。有字串,連結串列,集 合和有序集合。支援在伺服器端計算集合的並,交和補集(difference)等,
Python檔案操作中的a,a+,w,w+幾種方式的區別 ——轉載
轉載:https://blog.csdn.net/qq_38059635/article/details/81606977 第一步 排除檔案開啟方式錯誤: r只讀,r+讀寫,不建立 w新建只寫,w+新建讀寫,二者都會將檔案內容清零 (以w方式開啟,不能讀出。w+可讀
Python檔案操作中的a,a+,w,w+,rb+,rw+,ra+幾種方式的區別
access_mode:開啟方式,r讀,w寫,a追加,r+ w+ a+ 都是以讀寫方式開啟,rb二進位制讀,wb二進位制寫,rb+ wb+ ab+二進位制讀寫 buffering:預設值 二、對檔案進行操作 將檔案中的內容讀入到一個字串變數/列表中 函式:read(),
【由淺至深】redis 現實發布訂閱的幾種方式
前言 提到訊息佇列,最熟悉無疑是 rabbitmq,它基本是業界標準的解決方案。本文詳細介紹 redis 多種現實輕訂閱方法,作者認為非常有趣並加以總結,希望對有需要的朋友學習 redis 功能有一定的帶入作用。 方法一:SUBSCRIBE + PUBLISH //程式1:使用程式碼現實訂閱端 var s
redis判斷key是否存在(過期)的幾種方式
exist命令 EXISTS key 檢查給定 key 是否存在。 可用版本:>= 1.0.0 時間複雜度:O(1) 返回值: 若 key 存在,返回 1
Python操作excel的幾種方式--xlrd、xlwt、openpyxl
釋出時間:2016-05-13, 17:54:19 最後更新:2016-05-13, 21:29:30 在處理excel資料時發現了xlwt的侷限性–不能寫入超過65535行、256列的資料(因為它只支援Excel 2003及之
樹莓派的GPIO操作幾種方式
轉載出處1、http://www.waveshare.net/study/article-600-1.html2、http://www.waveshare.net/study/article-601-1.htmla)使用shell指令碼方式b)使用sysfs方式,編寫.c檔案
redis 儲存自定義java物件有幾種方式
最近去面試,碰到面試官提問,如果要把一個自定義的java物件儲存到redis中,除了一般使用json和序列化之外,還有一種,可以配置redis的配置檔案,操作hash型別,直接使用HGETALL (或
session存入redis的幾種方式
1,int_set('session.save_path',值);2,session.save_path="http"//127.0.0.1:6379?Aath=密碼";3,session_set_save_handler(open,close,read,write,dele
.net操作SQL資料庫中的幾種方式
1:直接操作 省略………. sqlConnection conn = new sqlConnection(); conn.Open(); conn.Close(); 2:通過using直接操作,不用關閉 sqlConnection conn = new sqlConnec