Redis介紹及Jedis測試

来源:https://www.cnblogs.com/wlandwl/archive/2018/01/22/redis.html
-Advertisement-
Play Games

1.Redis簡介 Redis 是一個開源(BSD許可)的,記憶體中的數據結構存儲系統,它可以用作資料庫、緩存和消息中間件。 它支持多種類型的數據結構,如 字元串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 與範圍查詢, b ...


1.Redis簡介

    Redis 是一個開源(BSD許可)的,記憶體中的數據結構存儲系統,它可以用作資料庫、緩存和消息中間件。 它支持多種類型的數據結構,如 字元串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 與範圍查詢, bitmaps, hyperloglogs 和 地理空間(geospatial) 索引半徑查詢。 Redis 內置了 複製(replication),LUA腳本(Lua scripting), LRU驅動事件(LRU eviction),事務(transactions) 和不同級別的 磁碟持久化(persistence), 並通過 Redis哨兵(Sentinel)和自動 分區(Cluster)提供高可用性(high availability)。Redis 是完全開源免費的,遵守BSD協議,是一個高性能的key-value資料庫。

    Redis 與其他 key - value 緩存產品有以下三個特點:

  1. Redis支持數據的持久化,可以將記憶體中的數據保存在磁碟中,重啟的時候可以再次載入進行使用。
  2. Redis不僅僅支持簡單的key-value類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。
  3. Redis支持數據的備份,即master-slave模式的數據備份。

2.Redis優勢

  1. 性能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
  2. 豐富的數據類型 – Redis支持二進位案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數據類型操作。
  3. 原子 – Redis的所有操作都是原子性的,意思就是要麼成功執行要麼失敗完全不執行。單個操作是原子性的。多個操作也支持事務,即原子性,通過MULTI和EXEC指令包起來。
  4. 豐富的特性 – Redis還支持 publish/subscribe, 通知, key 過期等等特性。
  5. Redis運行在記憶體中但是可以持久化到磁碟,所以在對不同數據集進行高速讀寫時需要權衡記憶體,因為數據量不能大於硬體記憶體。在記憶體資料庫方面的另一個優點是,相比在磁碟上相同的複雜的數據結構,在記憶體中操作起來非常簡單,這樣Redis可以做很多內部複雜性很強的事情。同時,在磁碟格式方面他們是緊湊的以追加的方式產生的,因為他們並不需要進行隨機訪問。

3.linux環境下安裝Redis

    1.下載地址:http://redis.io/download,下載最新版本的linux版本Redis。

    2.本教程使用的最新文檔版本為 4.0.6,下載文件後,上傳到linux伺服器上面,並解壓安裝。

     操作指令為:$ tar xzf redis-4.0.6.tar.gz     $ cd redis-4.0.6    $ make 

    3.make成功執行完後 redis- 4.0.6目錄會生成src 目錄,在一次執行命令:$ make install

         

    4.啟動redis服務,使用預設配置方式啟動:進入到redis-4.0.6/src目錄,執行啟動命令:redis-server 

    

    註意:這裡直接執行Redis-server 啟動的Redis服務,是在前臺直接運行的(效果如上圖),也就是說,執行完該命令後,如果Linux關閉當前會話,則Redis服務也隨即關閉。正常情況下,啟動Redis服務需要從後臺啟動,並且指定啟動配置文件。 

後臺啟動redis服務

  1. 首先編輯conf文件,將daemonize屬性改為yes(表明需要在後臺運行),並指定ip地址,開放redis埠號:6379。操作指令為:cd redis-4.0.6/ vi redis.conf
  2. 再次啟動redis服務,並指定啟動服務配置文件:  redis-server /usr/local/redis/etc/redis.conf    
  3. 在防火牆中開放埠:6379

     

    在本地電腦上,安裝一個redis客戶端連接工具,如:redisclient-win32.x86.1.5。利用連接工具可方便查看redis中設置的緩存數據,連接如圖所示:   

4.jedis操作Redis介紹

    jedis 是 Redis 官方首選的 Java 客戶端開發包,上手比較容易。jedis提供了以下三種操作方式:

  1. 單機單連接方式:此方式僅建議用於開發環境做調試用。
  2. 單機連接池方式:此方式適用於僅使用單個Redis實例的場景
  3. 多機分散式+連接池方式:此方式適用規模較大的系統,往往會有多個Redis實例做負載均衡。並且還實現主從備份,當主實例發生故障時,切換至從實例提供服務。現在常用方案有JedisCluster。使用JedisCluster連接使用這種方式時,預設Redis已經進行了集群處理,JedisCluster即針對整個集群的連接.

 

 jedis操作redis模式

(1)事務方式(Transactions)

    所謂事務,即一個連續操作,是否執行是一個事務,要麼完成,要麼失敗,沒有中間狀態。而redis的事務很簡單,他主要目的是保障,一個client發起的事務中的命令可以連續的執行,而中間不會插入其他client的命令,也就是事務的連貫性。

   測試截圖

 

(2)管道(Pipelining)

   管道是一種兩個進程之間單向通信的機制。那再redis中,為何要使用管道呢?有時候,需要採用非同步的方式,一次發送多個指令,並且,不同步等待其返回結果。這樣可以取得非常好的執行效率。管道模式測試代碼:

  @Test
    public void jedisPipelined() {
        Jedis jedis = new Jedis("192.168.210.128", 6379);
        Pipeline pipeline = jedis.pipelined();
        long start = System.currentTimeMillis();
        for (int i = 0; i < 1000; 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();
    }

   註意:事務和管道都是非同步模式。在事務和管道中不能同步查詢結果。如下代碼操作為非法操作:

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();  

(3)管道中調用事務

    在某種需求下,需要非同步執行命令,但是,又希望多個命令是有連續的,所以可採用管道加事務的調用方式。jedis是支持在管道中調用事務的。

(4)分散式直連同步調用與分散式連接池同步調用

    這個是分散式直接連接,並且是同步調用,每步執行都返回執行結果。如果,分散式調用代碼是運行線上程中,那麼分散式直連同步調用方式就不合適了,因為直連方式是非線程安全的,這個時候需使用選擇連接池調用。案例代碼:

//分散式直接鏈接並同步調用
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("Simple@Sharing SET: " + ((end - start)/1000.0) + " seconds");  
   
    sharding.disconnect();  
}  
//分散式結合線程池使用
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("Simple@Pool SET: " + ((end - start)/1000.0) + " seconds");  
   
    pool.destroy();  
}  

(5)分散式直連非同步調用與分散式連接池非同步調用

    操作與同步相對,案例代碼如下:

//分散式連接池非同步調用測試 線程池使用
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("Pipelined@Pool SET: " + ((end - start)/1000.0) + " seconds");  
    pool.destroy();  
}  

(6)安全線程連接池(JedisPool)   

   註意Jedis對象並不是線程安全的,在多線程下使用同一個Jedis對象會出現併發問題。為了避免每次使用Jedis對象時都需要重新構建,Jedis提供了JedisPoolJedisPool是基於Commons Pool 2實現的一個線程安全的連接池。

//線程池模式使用測試:   
   JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
    jedisPoolConfig.setMaxTotal(10);
    JedisPool pool = new JedisPool(jedisPoolConfig, "localhost", 6379);

    Jedis jedis = null;
    try{
        jedis = pool.getResource();
        jedis.set("pooledJedis", "hello jedis pool!");
        System.out.println(jedis.get("pooledJedis"));
    }catch(Exception e){
        e.printStackTrace();
    }finally {
        //還回pool中
        if(jedis != null){
            jedis.close();
        }
    }
    pool.close();

(7)多機分散式集合連接池使用

    此方式適用規模較大的系統,往往會有多個Redis實例做負載均衡。並且還實現主從備份,當主實例發生故障時,切換至從備用實例提供服務。如伺服器1掛掉後,可用伺服器2繼續支撐redis緩存處理。測試代碼:

**
 * Description:  多機分散式+連接池方式:
 * Copyright:  2018 CSNT. All rights reserved.
 * Company:CSNT
 *
 * @author wangling
 * @version 1.0
 */
public class MultipleJedisPoolTest {

    static JedisPoolConfig config;
    static ShardedJedisPool sharedJedisPool;

    static {
        // 生成多機連接List
        List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
        shards.add( new JedisShardInfo("127.0.0.1", 6379) );
        shards.add( new JedisShardInfo("192.168.210.128", 6379) );

        // 初始化連接池配置對象
        config = new JedisPoolConfig();
        config.setMaxIdle(10);
        config.setMaxTotal(30);
        config.setMaxWaitMillis(2*1000);
        // 實例化連接池
        sharedJedisPool = new ShardedJedisPool(config, shards);

    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // 從連接池獲取Jedis連接
        ShardedJedis shardedJedisConn = sharedJedisPool.getResource();
        shardedJedisConn.set("Lemon", "Hello,my name is Lemon");
        System.out.println(shardedJedisConn.get("Lemon"));
        // 釋放連接
        close(shardedJedisConn, sharedJedisPool);

}
    private static void close(ShardedJedis shardedJedis,ShardedJedisPool sharedJedisPool){
        if(shardedJedis!=null &&sharedJedisPool!=null){
            sharedJedisPool.returnResource(shardedJedis);
        }
        if(sharedJedisPool!=null){
            sharedJedisPool.destroy();
        }
    }
}

5.Redis常用命令

1 連接操作命令

  • quit:關閉連接(connection)
  • auth:簡單密碼認證
  • help cmd: 查看cmd幫助,例如:help quit

2 持久化

  • save:將數據同步保存到磁碟
  • bgsave:將數據非同步保存到磁碟
  • lastsave:返回上次成功將數據保存到磁碟的Unix時戳
  • shutdown:將數據同步保存到磁碟,然後關閉服務

3 遠程服務控制

  • info:提供伺服器的信息和統計
  • monitor:實時轉儲收到的請求
  • slaveof:改變複製策略設置
  • config:在運行時配置Redis伺服器

4 對key操作的命令

  • exists(key):確認一個key是否存在
  • del(key):刪除一個key
  • type(key):返回值的類型
  • keys(pattern):返回滿足給定pattern的所有key
  • randomkey:隨機返回key空間的一個
  • keyrename(oldname, newname):重命名key
  • dbsize:返回當前資料庫中key的數目
  • expire:設定一個key的活動時間(s)
  • ttl:獲得一個key的活動時間
  • select(index):按索引查詢
  • move(key, dbindex):移動當前資料庫中的key到dbindex資料庫
  • flushdb:刪除當前選擇資料庫中的所有key
  • flushall:刪除所有資料庫中的所有key

5 String

  • set(key, value):給資料庫中名稱為key的string賦予值value
  • get(key):返回資料庫中名稱為key的string的value
  • getset(key, value):給名稱為key的string賦予上一次的value
  • mget(key1, key2,…, key N):返回庫中多個string的value
  • setnx(key, value):添加string,名稱為key,值為value
  • setex(key, time, value):向庫中添加string,設定過期時間time
  • mset(key N, value N):批量設置多個string的值
  • msetnx(key N, value N):如果所有名稱為key i的string都不存在
  • incr(key):名稱為key的string增1操作
  • incrby(key, integer):名稱為key的string增加integer
  • decr(key):名稱為key的string減1操作
  • decrby(key, integer):名稱為key的string減少integer
  • append(key, value):名稱為key的string的值附加value
  • substr(key, start, end):返回名稱為key的string的value的子串

6 List

  • rpush(key, value):在名稱為key的list尾添加一個值為value的元素
  • lpush(key, value):在名稱為key的list頭添加一個值為value的 元素
  • llen(key):返回名稱為key的list的長度
  • lrange(key, start, end):返回名稱為key的list中start至end之間的元素
  • ltrim(key, start, end):截取名稱為key的list
  • lindex(key, index):返回名稱為key的list中index位置的元素
  • lset(key, index, value):給名稱為key的list中index位置的元素賦值
  • lrem(key, count, value):刪除count個key的list中值為value的元素
  • lpop(key):返回並刪除名稱為key的list中的首元素
  • rpop(key):返回並刪除名稱為key的list中的尾元素
  • blpop(key1, key2,… key N, timeout):lpop命令的block版本。
  • brpop(key1, key2,… key N, timeout):rpop的block版本。
  • rpoplpush(srckey, dstkey):返回並刪除名稱為srckey的list的尾元素,並將該元素添加到名稱為dstkey的list的頭部

7 Set

  • sadd(key, member):向名稱為key的set中添加元素member
  • srem(key, member) :刪除名稱為key的set中的元素member
  • spop(key) :隨機返回並刪除名稱為key的set中一個元素
  • smove(srckey, dstkey, member) :移到集合元素
  • scard(key) :返回名稱為key的set的基數
  • sismember(key, member) :member是否是名稱為key的set的元素
  • sinter(key1, key2,…key N) :求交集
  • sinterstore(dstkey, (keys)) :求交集並將交集保存到dstkey的集合
  • sunion(key1, (keys)) :求並集
  • sunionstore(dstkey, (keys)) :求並集並將並集保存到dstkey的集合
  • sdiff(key1, (keys)) :求差集
  • sdiffstore(dstkey, (keys)) :求差集並將差集保存到dstkey的集合
  • smembers(key) :返回名稱為key的set的所有元素
  • srandmember(key) :隨機返回名稱為key的set的一個元素

8 Hash

  • hset(key, field, value):向名稱為key的hash中添加元素field
  • hget(key, field):返回名稱為key的hash中field對應的value
  • hmget(key, (fields)):返回名稱為key的hash中field i對應的value
  • hmset(key, (fields)):向名稱為key的hash中添加元素field
  • hincrby(key, field, integer):將名稱為key的hash中field的value增加integer
  • hexists(key, field):名稱為key的hash中是否存在鍵為field的域
  • hdel(key, field):刪除名稱為key的hash中鍵為field的域
  • hlen(key):返回名稱為key的hash中元素個數
  • hkeys(key):返回名稱為key的hash中所有鍵
  • hvals(key):返回名稱為key的hash中所有鍵對應的value
  • hgetall(key):返回名稱為key的hash中所有的鍵(field)及其對應的value

6.源碼下載

7.源碼下載

在Git上面下載:https://github.com/wuya11/jedisDemo


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 數據倉庫(Data Warehouse)是一個面向主題的(Subject Oriented)、集成的(Integrate)、相對穩定的(Non-Volatile)、反映歷史變化(Time Variant)的數據集合,用於支持管理決策。是OLTP類型的數據處理。 數據處理大致可以分成兩大類:聯機事務處 ...
  • 大數據(big data)是指“無法用現有的軟體工具提取、存儲、搜索、共用、分析和處理的海量的、複雜的數據集合”。業界通常用4個V(即Volume、Variety、Value、Velocity)來概括大數據的特征。下麵我們將對大數據這四種特征做簡要的解釋: Volume : 指代大型數據集,一般在1 ...
  • hadoop完全分散式模式搭建和hive安裝 簡介 Hadoop是用來處理大數據集合的分散式存儲計算基礎架構。可以使用一種簡單的編程模式,通過多台電腦構成的集群,分散式處理大數據集。hadoop作為底層,其生態環境很豐富。 hadoop基礎包括以下四個基本模塊: hadoop基礎功能庫:支持其他h ...
  • mongodb預設是不能遠程連接的,而且在linux安裝完你會發現,它的目錄極其簡單,連個配置文件都沒有. 我的mongodb的版本是3.6,目前最新的.https://www.mongodb.com/mongodb-3.6 百度了一下看是有配置文件: mongodb.conf. 又檢查了下目錄確實 ...
  • MongoDB在互聯網項目中使用越來越多,佈署在雲端Linux伺服器上的mongoDB資料庫,大多存在遠程維護不便的問題,開放27017埠又將導致安全隱患。有個折中的辦法就是使用基於web的客戶端管理軟體進行資料庫的日常維護,TreeDMS資料庫管理系統剛好就可以滿足這些功能要求,實現基於WEB方 ...
  • 一、概述 加密是一種安全措施,有時候甚至是法律要求。作為攻破Windows系統的最後一道防線,通過加密可以保證在沒有密鑰的情況下獲取備份或者物理介質變得毫無意義。 二、概念 加密層次結構 加密層次結構的每一層是如何對它下麵的一層進行加密的,並且顯示了最常用的加密配置。對層次結構的開始進行的訪問通常受 ...
  • 增 #1、沒有指定_id則預設ObjectId,_id不能重覆,且在插入後不可變 #2、插入單條 user0={ "name":"egon", "age":10, 'hobbies':['music','read','dancing'], 'addr':{ 'country':'China', 'c ...
  • 針對Oracle數據遷移,我們可能會用到expdp/impdp的方式,有時候需要大表、lob欄位等可能會消耗過大的臨時表空間和undo表空間,所以一般我們根據導出日誌,在導入前適當調整表空間大小。否則我們可能會遇到以下問題: 1、臨時表空間爆滿,無法擴展 ORA-1652: unable to ex ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...