Redis はすぐに開始して適用できます。この記事を読むだけです。

1 はじめに

Redis は、オープン ソース、メモリベース、永続的、高性能、キー値ベースの Nosql データベースであり、データベース、キャッシュ、メッセージ ブローカー、ストリーミング メディア エンジンとして使用されます。

アプリケーション シナリオ: kv データベースとしてのストレージ価値は、対応する MongoDB ほど良くありません。メッセージ キューとしては、Kafka ほど優れたものではありませんが、その役割は依然としてキャッシュであり、その「キャッシュ」の性質は「データ ストレージ」の性質よりもはるかに優れています。

デフォルトのポート: 6379

2. データ型

Redis は kv ストレージに基づいており、キー タイプは文字列タイプのみにすることができます。空の文字列も修飾キーであり、値のタイプはさまざまです。

キー値の選択原則:キー値は長すぎる必要はありません。長すぎるとメモリを消費し、データ内でそのようなキー値を見つけるための計算コストが高くなります。キー値は短すぎてはなりません。短すぎると可読性が低下します。貧乏になるだろう。

公式に発表された最新のサポートされている値の型は次のとおりです。私たちがよく知っている 5 つの基本的なデータ型に加えて、見慣れないデータ型も多数あります。興味がある場合は、公式 Web サイトで学習できます。この記事では、一般的に使用される 5 つのデータ構造、 StringListHashSetZset (つまり、ソートされたセット)に焦点を当てます。各データ構造の具体的な説明については、「CRUD 操作」モジュールを参照してください。
ここに画像の説明を挿入

3. クラスターのアーキテクチャ

MongoDB に似た Redis クラスターを構築するには 3 つの方法があります。

1. マスタースレーブモード (マスター/スレーブ)
マスターは複数のスレーブを持つことができ、スレーブはマスターノードのデータを同期します。デフォルトでは、マスター ノードは読み取りと書き込みが可能で、スレーブ ノードは読み取りと書き込みのみの操作が禁止されています。

欠点: マスター ノードがハングアップすると、残りのスレーブはマスターになれないため、redis は外部書き込みサービスを提供できなくなります。

2. Sentinel センチネル モード
Sentinel の中国語の意味は番兵と警備員であり、独立したプロセスです。つまり、マスター/スレーブ モードでは、マスター ノードがハングアップすると、スレーブ ノードはアクティブにマスター ノードを選択できないため、これを行うために 1 つ以上のセンチネルを配置します。がハングアップすると、Sentinel はスレーブからマスターを再選出します。

センチネル モードは基本的に一般的な生産のニーズを満たすことができ、可用性が高くなります。ただし、データ量が大きすぎて 1 台のサーバーに格納できない場合は、マスタースレーブモードやセンチネルモードでは対応できず、格納するデータを断片化して複数の Redis インスタンスに格納する必要があります。

3. クラスター モード (フラグメンテーション + コピー モード)
クラスター モードの登場は、単一マシン Redis の容量制限の問題を解決し、特定のルールに従って Redis データを複数のマシンに分散して Redis 分散ストレージを実装することです。 、それぞれの異なるコンテンツが Redis ノードに保存されます。

各ノード (マスター) はクラスターの高可用性を確保するために複数のスレーブを導入できるため、2 つのレプリカと 3 つのフラグメントが構成されている場合は、6 つの Redis インスタンスが必要です。
Redis データは特定のルールに従ってクラスター内のさまざまなマシンに割り当てられるため、データ量が増加した場合に新しいマシンを追加して拡張するのに非常に便利です。
このモードは、大量のデータをキャッシュする必要がある場合に適しています。データ量がそれほど多くない場合は、Sentinel を使用してください。

Redis-Cluster は非中央構造を採用しています。クライアントは、中間プロキシ層を介さずに Redis ノードに直接接続されます。クライアントは、クラスター内のすべてのノードに接続する必要はありませんが、クラスター内の使用可能な任意のノードに接続できます。

Redis クラスターには次の重要な機能があります:
(1). Redis クラスターのシャーディング機能は、スペースが 16384 個のスロットに分割され、特定のノードがスロットの一部を担当し、キー ペア 16384 の残りの部分が異なるスロットに割り当てられます。
(2)、Redis クラスターはある程度の可用性を提供し、特定のノードがダウンしている (配下にスレーブが存在しない、またはすべてのスレーブがダウンしている) 場合、またはノードに到達できない場合でもコマンドの処理を続行できます。
(3) Redis クラスターにはセントラル ノードもプロキシ ノードもありません。クラスターの最も重要な設計目標の 1 つは、線形スケーラビリティを達成することです。

4. Redisクライアントシェルコマンド

4.1. スクリプトコマンド

まず、 redis-serverredis-cliという 2 つのスクリプト コマンドを紹介します。

1. redis-server コマンドは、redis サービスを開始するために使用されます。

#启动redis
redis-server redis.conf
#查看版本
redis-server -v

2. redis-cli コマンドを使用して、redis サーバーに接続し、コマンドラインモードに入ります。

#连接 (-p指定端口,-a指定密码,-c 集群模式)
redis-cli -h 172.28.226.5 -p 6379 -a $password -c

#注意:在Redis6.0之前的版本中,如上面指定的是默认用户default的密码,redis以前的版本也只支持单用户访问,也就是没有用户名这个概念。

4.2. 基本的なコマンドラインコマンド

Redis は非常に豊富なコマンドを提供します。以下では一般的に使用されるコマンドのみを紹介します。その他のコマンドは https://redis.io/commands/ で確認でき、各コマンドのより詳細な使用方法を検索できます。また、「ヘルプコマンド」からコマンドの使用方法を確認することもできます。
ここに画像の説明を挿入

1. 運用・保守コマンド

#测试连接是否可用,返回pang则表示连接可用
redis> PING
"PONG"

#查看redis统计信息
redis> info

#列出所有连接
redis> client list

#杀死某个连接
redis> client kill 127.0.0.1:43501

2. 基本的な操作コマンド

dbsize        #显示数据库中所有key的数量
keys *        #显示所有的key
exists mykey  #判断该键是否存在,存在返回1,不存在返回0
flushdb       #清空数据库
del mykey     #删除该键值
type key      #查看key的值类型
help command  #帮助命令,查看命令的用法,如help get

4.3. CRUD操作

  1. スティング

    文字列型。最も単純で最もよく使用される値の型。コマンドラインでは、キーと値の両方を引用符なしで指定できます。

    #设值,取值,删值基本操作,name就是我们设置的key值,注意以下所有命令command后紧跟的字符串都是key值。
    set name shengr
    get name
    del name
    
    #对已经存在的key设置过期时间,单位秒
    expire name 60
    
  2. リスト

    リスト型は Java の配列 ArrayList に似ています。

    リスト内の要素は文字列型であり、要素の順序は挿入順序と同じです。リストの先頭と末尾の追加と削除の速度は速く、中間の追加と削除の速度は遅くなりますが、通常の使用プロセスでの要素の追加と削除は正常であり、リスト内の要素が表示される可能性があります繰り返し、リストのインデックスは左から右に 0 から始まり、右から左に -1 から始まります。

    # lpush 元素依次压入列表头部,一次可以压入一个或多个元素
    lpush words a b c d  	
    # rpush 元素依次插入到列表末位
    rpush words e f g
    # lrange 获取下标从start到end的元素,下标从0开始并且包含end处的值。另外,下标可以是负数,表示倒数第几个值,-1即表示最后一位。
    lrange words 0 -1 
    # lpop 从列表首位移除一个值
    lpop words 
    # rpop 从列表末尾移除一个值
    rpop words 
    
    # 获取List长度
    llen words
    # 通过下标获取值
    lindex words 1
    # 通过下标设置
    lset words 0 a
    
  3. ハッシュ

    ハッシュ タイプは Java の HashMap に似ているため、キーはマップ タイプの値 (kv ペアのセット) に対応します。

    ハッシュは、フィールドと関連する値で構成されるマップのキーと値のペアであり、フィールドと値は両方とも文字列型です。

    # hset 依次设置map中键值对,一次可以设置一个或多个
    hset user name shengr age 12 city sz
    # hget 获取map中某个field上的值
    hget user name
    # hgetAll 获取map中的所有field值
    hgetall user
    #hdel 删除map中的一个或多个指定fileld,不存在的字段忽略
    hdel user age city
    
    # hexists 判断字段是否存在,存在返回1,不存在返回0
    hexists user age
    # hkeys 获取map上的所有field:
    hkeys user
    # hvals 获取map上的所有value:
    hvals user
    # hlen 获取map中field个数:
    hlen user
    
  4. 設定

    コレクション型は Java の HashSet に似ており、一意のメンバーと順序付けされていない要素があり、要素は文字列型です。

    # sadd 往集合中加入元素,重复的元素无法插入
    sadd chars a b b c 
    # smembers 取出所有元素
    smembers chars 
    # srem 从集合中删除元素
    srem chars a 
    # scard 获取集合中元素个数
    scard chars
    
  5. 設定

    Java の TreeSet に似た順序付きコレクション タイプ。一意の順序付きメンバーを持ち、要素は文字列型で、各要素は浮動小数点スコア Score に関連付けられ、コレクションはスコア要素の昇順に配置されます。 (スコアは同じかマイナスになる可能性があります)。

    # zadd 往集合中加入带分值的元素
    zadd letters 1 a 3.1 b 4 c
    # zrange 根据下标获取集合中的元素,正序
    zrange letters 0 -1
    # zrem 从集合中删除元素
    zrem letters a
    # zcard 返回元素个数
    zcard letters
    # zscore 返回某个元素的分值
    zscore letters b
    # zincrby 给某个元素的分值加上一个值,减去一个值使用负数即可
    zincrby letters 2 b
    

5. RedisのJAVAクライアント

5.1. 3 つの一般的な Java クライアント

ジェダイ

昔ながらの Redis クライアントは使いやすく、Redis コマンドの包括的なサポートを提供します。これについては以下で焦点を当てます。Jedis のメソッドは基盤となる Redis API を呼び出します。つまり、Jedis の Java メソッドは基本的に Redis API と一致しています。Redis API を理解すると、Jedis をより上手に使用できるようになります。公式アドレス: https://github.com/redis/jedis

注: jedis はブロッキング I/O を使用し、そのメソッド呼び出しは非同期ではなく同期です。Jedis クライアント インスタンスはスレッドセーフではないため、Jedis は接続プール経由で使用する必要があります。

レタス

英語の直訳は「レタス」で、スレッドセーフな同期、非同期、およびリアクティブな使用のための高度な Java Redis クライアントです。クラスター、センチネル、パイプライン、コーデックのサポート。公式サイトアドレス:https://lettuce.io/

レディソン

RedisをベースにJavaのインメモリデータグリッド機能(In-Memory Data Grid)を実装し、一連の分散Javaオブジェクトを提供する高度な分散連携Redisクライアントです。Jedis および Lettuce クライアントは、Reids データベースに対する CRUD (追加、削除、変更、クエリ) 操作に重点を置いているのに対し、Redisson API は分散開発に重点を置いています。公式サイトアドレス:https://redisson.org/
ここに画像の説明を挿入

5.2. Jedisクライアントの詳細説明

Jedis クライアント アクセス モードの概要:

Jedis クライアントは、スタンドアロン モード、シャーディング モード、およびクラスター モードのアクセス モードを同時にサポートします。スタンドアロン モードでのデータ アクセスはJedis クラス オブジェクトを構築することによって実現され、シャーディング モードでのデータ アクセスはShardedJedis クラス オブジェクトを構築することによって実現されます。JedisCluster クラス オブジェクトを構築することで実現され、クラスター モードでのデータ アクセス。このうちShardedJedisは、Redisにクラスタ機能が無い以前にクライアント側で実装されていたデータ分散スキームですが、現在ではJedisClusterを利用することが可能です。

5.2.1. スタンドアロンモードのデータアクセス

1. Jedis 接続オブジェクトを作成する

IP とポートを使用して Jedis クラス オブジェクトを構築します。Redis にパスワードが設定されている場合は、認証に auth メソッドを使用する必要があります。

Jedis jedis = new Jedis("172.28.226.5",6379);
jedis.auth("$pwd");

2.文字列型

//1,设置k-v值
jedis.set("name","shengr");
//2,获取k对应v值
String username=jedis.get("name");
System.out.println(username);
//3,设置值的同时指定过期时间,方法为setex,第二参数指定过期时间,单位秒
jedis.setex("flag",30,"1");
//4,删除key
jedis.del("flag");
//5,关闭连接
jedis.close();

3. リスト型

//lpush 元素依次插入到列表首位
jedis.lpush("words","a","b");
//rpush 元素依次插入到列表末位
jedis.rpush("words","c","d","e");
//lrange 获取下标从start到end的元素,下标从0开始并且包含end处的值。另外,下标可以是负数,表示倒数第几个值,-1即表示最后一位。
List<String> words = jedis.lrange("words", 0, -1);
System.out.println(words);
//lpop 从列表首位弹出一个值
String word1 = jedis.lpop("words");
//rpop 从列表末位弹出一个值
String word2 = jedis.rpop("words");
System.out.println(word1+"--"+word2);

4. ハッシュの種類

キーはフィールド値のセットに対応します

//设值
jedis.hset("user","name","shengr");
jedis.hset("user","age","12");
jedis.hset("user","city","sz");
//获取单个值
String name=jedis.hget("user","name");
System.out.println(name);
//遍历所有值
Map<String,String> user = jedis.hgetAll("user");
for (String key : user.keySet()) {
    
    
String value = user.get(key);
System.out.println(key+":"+value);
}
//删除key中的一个或多个指定fileld,不存在的字段忽略
jedis.hdel("user","city","sex");

5. セットタイプ

コレクション内の要素は一意であるため、重複した要素を追加することは無効です

//设值
jedis.sadd("distinctWords","a","b","a");
//获取所有值
Set<String> distinctWords = jedis.smembers("distinctWords");
System.out.println(distinctWords);

6.Zsetタイプ

Ordered Set タイプ。ランキング スコアはスコアによって指定され、要素はこのスコアに従って小さいものから大きいものへと並べ替えられます。

jedis.zadd("sortedset",3,"ding");
jedis.zadd("sortedset",5,"seng");
jedis.zadd("sortedset",4,"ming");
Set<String> sortedset = jedis.zrange("sortedset", 0, -1);
System.out.println(sortedset);

完全な実行コードは次のとおりです。

public class JedisTest {
     
     
   private static Jedis jedis;
   //通过静态代码块进行初始化值
   static {
     
     
       jedis = new Jedis("172.28.226.5",6379);
       jedis.auth("$pwd");
   }

   //1,String类型
   public static void op01(){
     
     
       //1,设置k-v值
       jedis.set("name","shengr");
       //2,获取k对应v值
       String username=jedis.get("name");
       System.out.println(username);
       //3,设置值的同时指定过期时间,方法为setex,第二参数指定过期时间,单位秒
       jedis.setex("flag",30,"1");
       //4,删除key
       jedis.del("flag");
       //5,关闭连接
       jedis.close();
   }
   //2,List类型
   public static void op02(){
     
     
       //lpush 元素依次插入到列表首位
       jedis.lpush("words","a","b");
       //rpush 元素依次插入到列表末位
       jedis.rpush("words","c","d","e");
       //lrange 获取下标从start到end的元素,下标从0开始并且包含end处的值。另外,下标可以是负数,表示倒数第几个值,-1即表示最后一位。
       List<String> words = jedis.lrange("words", 0, -1);
       System.out.println(words);
       //lpop 从列表首位弹出一个值
       String word1 = jedis.lpop("words");
       //rpop 从列表末位弹出一个值
       String word2 = jedis.rpop("words");
       System.out.println(word1+"--"+word2);
   }

   //3,Hash类型,同一个key对应一组k-v值
   public static void op03(){
     
     
       //设值
       jedis.hset("user","name","shengr");
       jedis.hset("user","age","12");
       jedis.hset("user","city","sz");
       //获取单个值
       String name=jedis.hget("user","name");
       System.out.println(name);
       //遍历所有值
       Map<String,String> user = jedis.hgetAll("user");
       for (String key : user.keySet()) {
     
     
           String value = user.get(key);
           System.out.println(key+":"+value);
       }
       //删除key中的一个或多个指定fileld,不存在的字段忽略
       jedis.hdel("user","city","sex");
   }

   //4-1,Set类型:集合中元素唯一
   public static void op04(){
     
     
       jedis.sadd("distinctWords","a","b","a");
       Set<String> distinctWords = jedis.smembers("distinctWords");
       System.out.println(distinctWords);

   }
   //4-2,有序Set类型: score指定排名分值,元素按照此分值从小到大排序
   public static void op05(){
     
     
       jedis.zadd("sortedset",3,"ding");
       jedis.zadd("sortedset",5,"seng");
       jedis.zadd("sortedset",4,"ming");
       Set<String> sortedset = jedis.zrange("sortedset", 0, -1);
       System.out.println(sortedset);
   }

   public static void main(String[] args) {
     
     
       op01();
       op02();
       op03();
       op04();
       op05();
   }
}

5.2.2. クラスターモードのデータアクセス

クラスター モード アクセスの場合、構築する必要があるのは、Jedis オブジェクトではなく、JedisCluster オブジェクトです。オブジェクトは変更されていますが、上記のデータ型にアクセスする方法は Jedis オブジェクトの方法とまったく同じです。ここでは、JedisCluster 接続オブジェクトを作成する方法だけに注目する必要があります。

1. Jedis接続プール

jedis の接続プールは JedisPool と呼ばれます. 接続プールが作成されると、接続プールから接続を取得できます. クライアントは TCP プロトコルを使用して Redis に接続します. 直接接続方法は毎回 TCP 接続を確立する必要があります, Jedis 接続は初期化されるため、毎回 Jedis 接続プールから借用するだけで済み、借用と返却の操作はローカルで実行され、同時同期のオーバーヘッドはわずかです。これは、新しい TCP 接続を作成するオーバーヘッドよりもはるかに小さいです。

接続プール構成プロパティ (JedisPoolConfig オブジェクトを通じてプロパティを設定):

  • 最大合計

    接続プールの容量、つまり利用可能な接続の最大数。

  • マックスアイドル

    アイドル状態の接続の最大数。デフォルト値は 8 です。

  • maxWaitMillis

    使用可能な接続を待機する最大時間 (ミリ秒単位)。デフォルト値は -1 で、タイムアウトしないことを意味します。

  • テストオンリターン

    ブール値。このプロパティが true の場合、borrowObject メソッドを呼び出して接続プールから接続を取得する前に、検証のために validateObject メソッドが呼び出されます。検証が失敗した場合、接続は接続プールから削除され、破棄されます。同時に、新しい接続オブジェクトを借用しようとします。

  • テストオンボロー

    ブール値。このプロパティが true の場合、returnObject メソッドが呼び出されて接続が接続プールに返されると、validateObject メソッドが呼び出されて現在の接続を検証し、検証が失敗した場合は接続が破棄されます。

2. JedisCluster 接続オブジェクトを作成する

ここに画像の説明を挿入

構築メソッドによって作成され、すべてのパラメータを含む標準構築メソッド パラメータは次のとおりです。

  • ホストとポート

    HostAndPort はクラスター内の単一ノードの IP およびポート情報を表し、クラスター内の複数のノードを Set コレクションに配置できます。

  • 接続タイムアウト

    接続タイムアウト (ミリ秒単位)

  • soTimeout

    データの読み取りと書き込みのタイムアウト (ミリ秒単位)

  • 最大試行数

    最大再接続数

  • パスワード

    パスワード

  • jectPoolConfig

    接続プールのプロパティをカプセル化する JedisPoolConfig オブジェクト

    完全な実行コードは次のとおりです。

    public class JedisClusterTest {
           
           
       public static JedisCluster getJedisCluster() {
           
           
    
           //1设置集群节点的ip和端口信息,集群有多个节点需要添加多个
           Set<HostAndPort> hostAndPorts = new HashSet<HostAndPort>();
           HostAndPort hostAndPort = new HostAndPort("172.28.226.5",6379);
           hostAndPorts.add(hostAndPort);
           //2设置密码
           String password = "$pwd";
           //3连接超时时间
           int connectTimeout = 5000;
           //4读写超时时间
           int soTimeout = 5000;
           //5最大重连次数
           int maxAttempts = 3;
           //6连接池参数
           JedisPoolConfig jedisPoolConfig = getJedisPoolConfig();
    
           JedisCluster jedisCluster = new JedisCluster(hostAndPorts, connectTimeout, soTimeout, maxAttempts, password, jedisPoolConfig);
           //注意:JedisCluster最好设置成单例,且一般不需要执行close操作,而是由连接池管理。
           return jedisCluster;
       }
       private static JedisPoolConfig getJedisPoolConfig() {
           
           
           //1,pool容量,即最大连接数
           int maxTotal = 1024;
           //2,pool最大空闲连接数,默认值是8
           int maxIdle = 200;
           //3,等待可用连接的最大时间,单位是毫秒,默认值为-1,表示永不超时。
           int maxWaitMillis = 10000;
           //4,在返回一个连接对象时,是否进行有效性检查
           boolean testOnReturn = true;
           //5,借用一个连接对象时,是否进行有效性检查
           boolean testOnBorrow = true;
    
           JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
           jedisPoolConfig.setMaxTotal(maxTotal);
           jedisPoolConfig.setMaxIdle(maxIdle);
           jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
           jedisPoolConfig.setTestOnReturn(testOnReturn);
           jedisPoolConfig.setTestOnBorrow(testOnBorrow);
    
           return jedisPoolConfig;
       }
       public static void main(String[] args) {
           
           
           JedisCluster jc=getJedisCluster();
           jc.set("myname","shengr");
           System.out.println(jc.get("myname"));
       }
    }
    

5.2.3. Redis の一般的な例外

Exception in thread "main" redis.clients.jedis.exceptions.JedisMovedDataException: MOVED 14315 172.24.226.7:6379
	at redis.clients.jedis.Protocol.processError(Protocol.java:115)
	at redis.clients.jedis.Protocol.process(Protocol.java:161)
	at redis.clients.jedis.Protocol.read(Protocol.java:215)
	at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:340)
	at redis.clients.jedis.Connection.getStatusCodeReply(Connection.java:239)
	at redis.clients.jedis.Jedis.set(Jedis.java:121)
	at redisClient.JedisTest.op01(JedisTest.java:24)
	at redisClient.JedisTest.main(JedisTest.java:52)

問題の原因: MOVED は、現在 Redis クラスター モードであることを示します。Jedis クラス オブジェクト アクセスをクラスター モードで使用し、データ アクセス メソッドを Jedis クラス オブジェクト スタンドアロン モードで使用しています。

解決策: 接続オブジェクトを Jedis から JedisCluster に変更するだけです。

ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/qq_36756227/article/details/129764672