1. 程式人生 > >jedis學習筆記【1】

jedis學習筆記【1】

redis 指令:

原始碼地址:

maven依賴:

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.8.1</version>
</dependency>
  • 原理:

jedis

jedis底層主要有兩個類:
redis.clients.jedis.Protocol
redis.clients.jedis.Connection
Connection負責client與server之間通訊,Protocol是client與server之間通訊協議。

  • 主要方法:
public class Connection implements Closeable {
private static final byte[][] EMPTY_ARGS = new byte[0][];
    private String host = "localhost"; //redis伺服器地址(預設"localhost")
    private int port = 6379;//port:服務端號(預設6379)
    private Socket socket;
    private RedisOutputStream outputStream;//redis-client傳送給redis-server的內容
private RedisInputStream inputStream;//redis-server返回給redis-client的內容 private int pipelinedCommands = 0;//管道命令數 private int connectionTimeout = 2000;//連線超時時間(預設2000ms) private int soTimeout = 2000;//響應超時時間(預設2000ms) private boolean broken = false; ... /**主要方法*/ //連線 public void connect() { if
(!this.isConnected()) { try { this.socket = new Socket(); this.socket.setReuseAddress(true); this.socket.setKeepAlive(true); this.socket.setTcpNoDelay(true); this.socket.setSoLinger(true, 0); this.socket.connect(new InetSocketAddress(this.host, this.port), this.connectionTimeout); this.socket.setSoTimeout(this.soTimeout); this.outputStream = new RedisOutputStream(this.socket.getOutputStream()); this.inputStream = new RedisInputStream(this.socket.getInputStream()); } catch (IOException var2) { this.broken = true; throw new JedisConnectionException(var2); } } } //傳送命令內容 protected Connection sendCommand(Command cmd, byte[]... args) { try { this.connect(); Protocol.sendCommand(this.outputStream, cmd, args); ++this.pipelinedCommands; return this; } catch (JedisConnectionException var6) { JedisConnectionException ex = var6; try { String errorMessage = Protocol.readErrorLineIfPossible(this.inputStream); if(errorMessage != null && errorMessage.length() > 0) { ex = new JedisConnectionException(errorMessage, ex.getCause()); } } catch (Exception var5) { ; } this.broken = true; throw ex; } } } //協議 public final class Protocol { //命令的傳送都是通過redis.clients.jedis.Protocol的sendCommand來完成的,就是對RedisOutputStream寫入位元組流 /** *[*號][訊息元素個數]\r\n ( 訊息元素個數 = 引數個數 + 1個命令) *[$號][命令位元組個數]\r\n *[命令內容]\r\n *[$號][引數位元組個數]\r\n *[引數內容]\r\n *[$號][引數位元組個數]\r\n *[引數內容]\r\n */ private static void sendCommand(RedisOutputStream os, byte[] command, byte[]... args) { try { os.write((byte)42); os.writeIntCrLf(args.length + 1); os.write((byte)36); os.writeIntCrLf(command.length); os.write(command); os.writeCrLf(); byte[][] e = args; int var4 = args.length; for(int var5 = 0; var5 < var4; ++var5) { byte[] arg = e[var5]; os.write((byte)36); os.writeIntCrLf(arg.length); os.write(arg); os.writeCrLf(); } } catch (IOException var7) { throw new JedisConnectionException(var7); } } } //返回的資料是通過讀取RedisInputStream 進行解析處理後得到的 /** * public static final byte PLUS_BYTE = 43; * public static final byte DOLLAR_BYTE = 36; * public static final byte ASTERISK_BYTE = 42; * public static final byte COLON_BYTE = 58; * "+": 狀態回覆(status reply) PLUS_BYTE * * <pre> * 狀態回覆通常由那些不需要返回資料的命令返回,這種回覆不能包含新行。 * eg: * cli: set name zhangsan * server: +OK * </pre> * * "$": 批量回復(bulk reply) DOLLAR_BYTE * 伺服器使用批量回復來返回二進位制安全的字串,字串的最大長度為 512 MB。 * eg: * cli: get name * server: $8\r\nzhangsan\r\n * 空批量回復: * 如果被請求的值不存在, 那麼批量回復會將特殊值 -1 用作回覆的長度值。當請求物件不存在時,客戶端應該返回空物件,而不是空字串。 * * "*": 多條批量回復(multi bulk reply) ASTERISK_BYTE * * 多條批量回復是由多個回覆組成的陣列, 陣列中的每個元素都可以是任意型別的回覆, 包括多條批量回複本身。 * eg: * cli: lrange mylist 0 3 * server: *4\r\n * :1\r\n * :2\r\n * :3\r\n * $3\r\n * foo\r\n * 多條批量回復也可以是空白的, * eg: * cli: lrange mylist 7 8 * server: *0\r\n * 無內容的多條批量回復(null multi bulk reply)也是存在的, 比如當 BLPOP 命令的阻塞時間超過最大時限時, 它就返回一個無內容的多條批量回復, 這個回覆的計數值為 -1 : * eg: * cli: blpop key 1 * server: *-1\r\n * 多條批量回復中的元素可以將自身的長度設定為 -1 , 從而表示該元素不存在, 並且也不是一個空白字串(empty string)。 * * ":": 整數回覆(integer reply) COLON_BYTE * * 整數回覆就是一個以 ":" 開頭, CRLF 結尾的字串表示的整數。 * eg: * cli: exists name * server: :1 * * "-": 錯誤回覆(error reply) MINUS_BYTE */ private static Object process(RedisInputStream is) { byte b = is.readByte(); if(b == 43) { return processStatusCodeReply(is); } else if(b == 36) { return processBulkReply(is); } else if(b == 42) { return processMultiBulkReply(is); } else if(b == 58) { return processInteger(is); } else if(b == 45) { processError(is); return null; } else { throw new JedisConnectionException("Unknown reply: " + (char)b); } } }
  • 示例:

以Jedis的get方法為例:

public String get(String key) {
        this.checkIsInMultiOrPipeline();
        this.client.sendCommand(Command.GET, new String[]{key});
        return this.client.getBulkReply();
    }

1:this.checkIsInMultiOrPipeline();
進行無事務檢查 Jedis不能進行有事務的操作 帶事務的連線要用redis.clients.jedis.Transaction類。
2:this.client.sendCommand(Command.GET, new String[]{key});
2.1:redis.clients.jedis.Connection connect()方法建立連線
2.2:public final class Protocol sendCommand()方法向RedisOutputStream寫入命令
2.3:在命令寫入成功之後,會將Connection的piplinedCommands 屬性自增一,表示在管道中已經有一個命令了
3:return this.client.getBulkReply();
get方法使用getBulkReply()獲取返回結果,其他見上文redis.clients.jedis.Protocol process()方法

  • pipeline

redis是一個cs模式的tcp server,使用和http類似的請求響應協議。一個client可以通過一個socket連線發起多個請求命令。每個請求命令發出後client通常會阻塞並等待redis服務處理,redis處理完後請求命令後會將結果通過響應報文返回給client。
所以在多條命令需要處理時,使用pipeline效率會快得多。
通過pipeline方式當有大批量的操作時候。我們可以節省很多原來浪費在網路延遲的時間。pipeline方式將client端命令一起發出,redis server會處理完多條命令後,將結果一起打包返回client,從而節省大量的網路延遲開銷。需要注意到是用 pipeline方式打包命令傳送,redis必須在處理完所有命令前先快取起所有命令的處理結果。打包的命令越多,快取消耗記憶體也越多。所以並是不是打包的命令越多越好。具體多少合適需要根據具體情況測試。

  • pipeline 示例
 Pipeline pipeline = jedis.pipelined();
        pipeline.set("a","a");
        pipeline.get("a");
        pipeline.set("b","b");
        pipeline.get("b");
        pipeline.del("a");
        pipeline.get("a");
        List<Object> list = pipeline.syncAndReturnAll();
        for (Object o : list){
            System.out.println(o);
        }

結果如下:

OK
a
OK
b
1
null
  • 參考連結

相關推薦

jedis學習筆記1

redis 指令: 原始碼地址: maven依賴: <dependency> <groupId>redis.clients</groupId> <artifactId>jedi

響應式布局學習筆記1----基礎知識

網頁設計 water com 文章 tar 屏幕分辨率 優點 light gin 本篇文章主要解決:什麽是響應式布局?有什麽優點和缺點? 一 什麽是響應式布局? 伊桑·馬科特(Ethan Marcotte)在2010年首先提出了響應式網頁設計(RWD,Responsive

Tomcat學習筆記1--- WEB服務器、JavaEE、Tomcat背景

javascrip http .cn 目的 java log 進行 瀏覽器 靜態資源 本文主要講學習Tomcat需要知道的基礎知識。 一 Web服務器 Web服務器可以解析HTTP協議。當Web服務器接收到一個HTTP請求,會返回一個HTTP響應,例如送回一個HTML頁面。

爬蟲學習筆記1 使用 urllib 獲取 www 資源

1. 掌握普通網頁的獲取方法 檢視 urllib.request 的基本資訊 urllib.request 中最常用的方法是 urlopen() ,它也是我們使用 urllib 獲取普通網頁的基本方法。 在應用之前,我們先看一下 urllib 的原始碼,這是從事IT軟體類

學習筆記--Hystrix服務容錯學習筆記1

Hystrix具有服務降級、服務熔斷、執行緒和訊號隔離、請求快取、請求合併以及服務監控等功能。 文章目錄 1 簡單的配置: 1.1 引入Spring Cloud Hystrix 1.2 添加註解 1

吳恩達《deeplearning深度學習》課程學習筆記1(精簡總結)

畢業以後就沒再寫過部落格,又想起來了。 Ps:本文只是個人筆記總結,沒有大段的詳細講解,僅僅是將自己不熟悉和認為重要的東西總結下來,算是一個大綱,用的時候方便回憶和查詢。 Ps2:部分筆記內容見圖片。 相關課程內容 一、神經網路和深度學習 第一週 深

機器學習框架ML.NET學習筆記1基本概念

一、序言        微軟的機器學習框架於2018年5月出了0.1版本,2019年5月釋出1.0版本。期間各版本之間差異(包括名稱空間、方法等)還是比較大的,隨著1.0版釋出,應該是趨於穩定了。之前在園子裡也看到不少相關介紹的文章,對我的學習提供了不少幫助。由於目前

spring boot 2.1學習筆記 新特性介紹

搭建springboot2.X工程 本系列文章IDE都是用的是IntelliJ IDEA,springboot版本採用2.1.1 1.基於 Java 8,支援 Java 9,這意味著不可以使用JDK7 或更舊的版本執行SpringBoot2. 2.支援 Quar

spring boot 2.1學習筆記屬性配置

spring boot 2.1系列文章目錄 文章目錄 常規屬性配置 @value 啟動引數 application.properties 型別安全的屬性配置(強烈推薦)

python學習1

需要 靈活 執行 print 變量 信息 多說 格式 感謝 本人是個滲透小子 從開始接觸滲透已經將近四年了 現在目標就是python的學習與應用 今天聽了老男孩的python的課程所以心血來潮就來寫個文章 今天的內容很是多 主要學習了有幾個塊 1、 用戶的交互 使用inp

.NET學習日記1

之前 語句 logs 編碼器 ges images switch 並不是 聲明 不得不說,之前一年學習的內容基本上在第一章中都有所涉及,而且還講了很多不知道知識。看完第一張對多態和繼承都多了一些體會。在1.4前面的都有很認證的看過,也在vs上面驗證了一下。然後也明白了.N

TDD學習筆記一Unit Test - Stub, Mock, Fake 簡介

-i moc load customers eight foreach 存在 執行 repo 這篇文章簡介一下,如何通過 mock framework,來輔助我們更便利地模擬目標對象的依賴對象,而不必手工敲堆只為了這次測試而存在的輔助類型。 而模擬目標對象的部分,常見的有

Docker學習筆記安裝Redis

art port 再次 dock 使用 contain bash Go red 項目中使用到Redis,平常都是別人搭建的,今天試著在Google Cloud Platform 上搭建一個學習環境。 1.使用 docker pull redis 從docker hub中下載

system generator學習筆記01

分享 基本功 hle ima 安裝 分享圖片 use 內容整理 blank 作者:桂。 時間:2018-05-18 18:26:50 鏈接:http://www.cnblogs.com/xingshansi/p/9045914.html 前言 學習使用s

Grunt學習筆記3---- filter詳解

add 行處理 class 一個 特殊 col filter詳解 很多 https 本文主要講配置任務中的filter,包括使用默認fs.Stats方法名和自定義過濾函數。 通過設置filter屬性可以實現一些特殊處理邏輯。例如:要清理某個文件夾下的所有空文件夾,這時使用c

Python學習筆記Supervisor:使用Supervisor監控Tornado程序

Linux常見應用服務配置模式nginx和supervisor:採用主配置檔案+專案配置檔案 安裝(如果使用pip安裝注意看是否需要指定使用python2版本)   第一步:在Linux中使用apt-get 指令安裝 sudo apt-get install supervisor

Python學習筆記Nginx:Nginx使用與完全解除安裝

 安裝與啟動nginx 第一步:通過指令安裝包 sudo apt  install nginx  sudo apt install nginx   第二步:安裝成功後檢視相關配置檔案 ls /etc/nginx/ 在這裡主要是 conf.d

資料分析---《Python for Data Analysis》學習筆記01

《Python for Data Analysis》一書由Wes Mckinney所著,中文譯名是《利用Python進行資料分析》。這裡記錄一下學習過程,其中有些方法和書中不同,是按自己比較熟悉的方式實現的。   第一個例項:1.usa.gov data from bit.ly &n

資料分析---《Python for Data Analysis》學習筆記02

《Python for Data Analysis》一書由Wes Mckinney所著,中文譯名是《利用Python進行資料分析》。這裡記錄一下學習過程,其中有些方法和書中不同,是按自己比較熟悉的方式實現的。   第二個例項:MovieLens 1M Data Set  

OpenCV學習筆記方框濾波、均值濾波、高斯濾波

1.平滑處理 平滑處理(smoothing)也稱模糊處理(bluring),是一種簡單且使用頻率很高的影象處理方法。平滑處理的用途有很多,最常見的是用來減少影象上的噪點或者失真。在涉及到影象解析度時,平滑處理是非常好用的方法。 2.影象濾波與濾波器 影象濾波,指儘量保留影象細節特徵的條件