ホームページ データベース Redis Redis の高度な機能の紹介

Redis の高度な機能の紹介

Jan 13, 2021 am 10:11 AM
redis 高度な機能

Redis の高度な機能の紹介

リモート辞書サービスである Redis (Remote Dictionary Server) は、オープンソースのログタイプの Key-Value データベースであり、複数の言語で API を提供します。

(学習ビデオ共有: redis ビデオ チュートリアル )

1.redis パブリッシュおよびサブスクライブ モード

Redis は、リストのようなメッセージ キューを提供することに加えて、モードには、パブリッシュ/サブスクライブ モードを実装するための一連のコマンドも提供されます。例えば、Weiboやパブリックアカウントなどはすべてこれによって実現できます。

Redis の高度な機能の紹介

1.2 チャンネルへの登録

パブリッシャーは、サブスクライバーがメッセージを購読できる場所にメッセージを送信する必要があります。この場所がチャンネルです。加入者は 1 つ以上のチャネルに加入でき、このチャネルのすべての加入者がこのメッセージを受信します。

テスト用に 2 つのクライアントを開きます

客户端1 订阅channel1
127.0.0.1:6379> subscribe channel1
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel1"
3) (integer) 1

客户端2 发布一则消息
127.0.0.1:6379> publish channel1 test
(integer) 1

客户端1 订阅消息
127.0.0.1:6379> subscribe channel1
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel1"
3) (integer) 1
1) "message"
2) "channel1"
3) "test"
ログイン後にコピー

1.2 ルールによるサブスクライブ

サポートされていますか?および * プレースホルダー。 ?は 1 文字、* は 0 文字以上を表します。

4 つの redis-cli を開始します。1 つはメッセージのパブリッシャーとして、他の 3 つはサブスクライバーとしてです。
購読者 1: スポーツ関連の購読

psubscribe *sport
ログイン後にコピー

購読者 2: ニュース関連の購読

psubscribe news*
ログイン後にコピー

購読者 3: 天気関連の購読

psubscribe new weather*
ログイン後にコピー

パブリッシャー:

publish news-sport Kobe
publish news-music jaychou
publish news-weather rain
ログイン後にコピー

この時点で、サブスクライバ 1 は神戸を受信し、サブスクライバ 2 はすべての情報を受信し、サブスクライバ 3 は雨を受信します。

Redis の高度な機能の紹介

2.redis トランザクション

2.1 トランザクションを使用する理由

redis の 1 つのコマンドがアトミックであることは誰もが知っていますが、分離できない一連の操作として複数のコマンドを使用する必要がある場合は、トランザクションを使用する必要があります。
たとえば、分散ロックを実装するために setnx を使用する場合、通常は最初に分散ロックを設定し、次に del で例外が発生したときにロックが解放されないようにキーに Expire を設定します。ビジネスが処理された後、これら 3 つが必要になります。 del.implement で一連のコマンドとして使用される操作。
Redis トランザクションには 2 つの特徴があります:

  • キューに入った順に実行されます

  • 他のクライアント要求の影響を受けません

Redis のトランザクション設計には、multi (トランザクションの開始)、exec (トランザクションの実行)、dicard (トランザクションのキャンセル)、watch (監視) の 4 つのコマンドがあります。

2.2 の使用法トランザクション

送金シナリオ A と B がそれぞれ 100 元を持っており、A が 10 元を B に送金し、A が 10 元を減算し、B が 10 元を追加します

127.0.0.1:6379> set A 100
OK
127.0.0.1:6379> set B 100
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby A 10
QUEUED
127.0.0.1:6379> incrby B 10
QUEUED
127.0.0.1:6379> exec
1) (integer) 90
2) (integer) 110
127.0.0.1:6379> get A
"90"
127.0.0.1:6379> get B
"110"
ログイン後にコピー

multi コマンドでトランザクションを開きます。トランザクションをネストすることはできません。複数のマルチ コマンドは同じ効果を持ちます。
マルチを使用してトランザクションを開始した後、クライアントは複数のコマンドをサーバーに送信します。これらのコマンドはすぐには実行されず、キューに入れられます。 exec コマンドが呼び出されると、キュー内のコマンドが実行されます。
discard を使用してトランザクション キューをクリアできます。

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 1
QUEUED
127.0.0.1:6379> set k2 2
QUEUED
127.0.0.1:6379> discard
OK
127.0.0.1:6379> get k1
(nil)
127.0.0.1:6379> get k2
(nil)
ログイン後にコピー

トランザクションの実行時に問題が発生した場合、トランザクションはロールバックされますか?

実行前にエラーが発生しました (コマンド構文エラーなど)

127.0.0.1:6379> clear
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set name test
QUEUED
127.0.0.1:6379> hset user lisi
(error) ERR wrong number of arguments for 'hset' command
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get name
(nil)
ログイン後にコピー

実行後にエラーが発生しました (同じキーに対して異なるデータ型のコマンドを使用した場合)

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 1
QUEUED
127.0.0.1:6379> hset k1 a b
QUEUED
127.0.0.1:6379> exec
1) OK
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> get k1
"1"
ログイン後にコピー

Through上記の操作により、実行前のトランザクションでエラーが発生した場合はすべての操作がロールバックされ、実行後にエラーが発生した場合は間違ったコマンドのみが実行されないことがわかります。
トランザクションでエラーが発生したときに Redis がロールバックしないのはなぜですか?
上記の操作から、redis は命令の構文が間違っている場合にのみロールバックすることがわかり、命令の操作エラーは開発者によって引き起こされたバグです。例: int 型で 1 を実行し、その後誤って 2 を実行した場合、または実行した場合文字列型の場合は 1、ロールバックは適用されません

2.3 監視命令

Redis トランザクションに対して CAS オプティミスティック ロック操作を提供できます。つまり、複数のスレッドが特定の変数を更新します。古い値とメモリアドレスを比較し、等しい場合は新しい値に更新します。
watch を使用して 1 つ以上のキーを監視できます。トランザクションの開始後、exec が実行される前に監視対象のキーの少なくとも 1 つが変更された場合、トランザクション全体がキャンセルされます。

まず、クライアント1は礼金を監視するためのwatchを実行し、100

127.0.0.1:6379> set money 1000
OK
127.0.0.1:6379> watch money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incrby money 100
QUEUED
ログイン後にコピー

を増やすトランザクションを開始します。トランザクションが終了する前に、クライアント2は100

127.0.0.1:6379> decrby money 100
(integer) 900
ログイン後にコピー
#を減らします。 # #この時点で、クライアント 1 はトランザクションを終了し、金額は増加していませんが減少しており、トランザクションの変更が失敗したことを示しています

127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> get money
"900"
ログイン後にコピー

3. Lua スクリプト

Lua スクリプトは軽量のスクリプト言語であり、C 言語で書かれており、ストアド プロシージャに似ています。なぜ lua スクリプトを使用するのでしょうか?

一度に複数のコマンドを送信して、ネットワークのオーバーヘッドを削減します。Redis はスクリプトを全体として実行して、アトミック性 (この方法でトランザクションを置き換えることができます) とスクリプトの再利用を確保し、複数のクライアントが簡単にコマンドを完了できるようにします。同じロジックです。

3.1

を使用すると、次のコマンドを使用して lua スクリプトを呼び出すことができます。


eval script numkeys [key1 key2 key3 ....] [arg1 arg2 arg3 ....]
ログイン後にコピー

eval は lua スクリプトを実行します。

スクリプトはコンテンツを表します。 lua スクリプトの

numkeys キー番号

[key1 key2 key3 ....] 键名参数,表示在脚本中所用到的那些 Redis 键(key),这些键名参数可以在 Lua 中通过全局变量 KEYS 数组,用 1 为基址的形式访问( KEYS[1] , KEYS[2] ,以此类推)。

[arg1 arg2 arg3 ....] 全局变量,可以在 Lua 中通过全局变量 ARGV 数组访问,访问的形式和 KEYS 变量类似( ARGV[1] 、 ARGV[2] ,诸如此类)

来个简单的例子

127.0.0.1:6379> eval "return {KEYS[1],ARGV[1],KEYS[2],ARGV[2]}" 2 key1 key2 val1 val1
1) "key1"
2) "val1"
3) "key2"
4) "val1"
127.0.0.1:6379> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 val1 val1
1) "key1"
2) "key2"
3) "val1"
4) "val1"
ログイン後にコピー

在lua脚本如何调用redis命令呢?
我们可以使用 redis.call(command, key [param1, param2…])进行操作

commond redis的命令,如set,get等key 被操作的键[param1, param2…]表示给key的参数

127.0.0.1:6379> eval "redis.call('mset',KEYS[1],ARGV[1],KEYS[2],ARGV[2])" 2 name age lisi 18
(nil)
127.0.0.1:6379> mget name age
1) "lisi"
2) "18
ログイン後にコピー

以上命令等价于 mset name lisi age 18, key的数量为2,2 后面两个值为key,在之后就是args

直接在redis-cli中写lua脚本不够方便,通常我们会把脚本放在文件中,然后执行这个文件
我们在一个目录下新建一个test.lua的脚本,填写以下内容后执行。

root@VM-0-5-centos src]# mkdir testlua
[root@VM-0-5-centos src]# cd testlua/
[root@VM-0-5-centos testlua]# ll
total 0
[root@VM-0-5-centos testlua]# touch test.lua
[root@VM-0-5-centos testlua]# vim test.lua
redis.call('set',KEYS[1],ARGV[1])
return redis.call('get',KEYS[1])
[root@VM-0-5-centos testlua]# redis-cli --eval test.lua 1 myname , Armin
"Armin"
ログイン後にコピー

值得注意的是key和arg之间需要加上空格逗号空格(myname , Armin)

3.2 缓存lua脚本

之所以需要缓存lua脚本,这是因为每次调用的时候都将整个脚本传给redis服务端,会产生较大的网络开销。为了解决这个问题,Redis提供了evalsha命令,让开发人员通过脚本内容的SHA1摘要执行脚本。

那么怎么将生成这个SHA1并将脚本内容加载到缓存呢,这就用到script load命令去计算脚本的SHA1摘要并记录脚本到缓存中,执行evalsha时,redis会根据提供的摘要去脚本缓存找到对应脚本内容,如果找到则执行,否则返回错误提示: “NOSCRIPT No matching script. Please use EVAL”

127.0.0.1:6379> script load "return 'Hey boy'"
"3760855b303510c83f0be2e8acfb0be64113ae6e"
127.0.0.1:6379> evalsha 3760855b303510c83f0be2e8acfb0be64113ae6e 0
"Hey boy"
127.0.0.1:6379> script exists 3760855b303510c83f0be2e8acfb0be64113ae6e //判断是否存在
1) (integer)
ログイン後にコピー

Redis还给lua脚本的执行提供了超时时间,默认的超时时间为5s,超过5s之后redis会接受其他命令但是会返回一个"BUSY"的错误
可在redis.conf中修改指定参数

lua-time-limit 5000
ログイン後にコピー

Redis提供了个script kill的命令来终止正在运行的脚本

127.0.0.1:6379> set name lisi
(error) BUSY Redis is busy running a script. You can only call SCRIPT KILL or SHUTDOWN NOSAVE.
127.0.0.1:6379> script kill
OK
127.0.0.1:6379> set name lisi
OK
ログイン後にコピー

如果数据进行了修改操作,将无法使用script kill终止脚本,因为违反了原子性。此时只能通过shutdown nosave来强行终止redis。
shutdown nosave 和 shutdown 的区别在于 shutdown nosave 不会进行持久化 操作,意味着发生在上一次快照后的数据库修改都会丢失。

相关推荐:redis数据库教程

以上がRedis の高度な機能の紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Redisクラスターモードの構築方法 Redisクラスターモードの構築方法 Apr 10, 2025 pm 10:15 PM

Redisクラスターモードは、シャードを介してRedisインスタンスを複数のサーバーに展開し、スケーラビリティと可用性を向上させます。構造の手順は次のとおりです。異なるポートで奇妙なRedisインスタンスを作成します。 3つのセンチネルインスタンスを作成し、Redisインスタンスを監視し、フェールオーバーを監視します。 Sentinel構成ファイルを構成し、Redisインスタンス情報とフェールオーバー設定の監視を追加します。 Redisインスタンス構成ファイルを構成し、クラスターモードを有効にし、クラスター情報ファイルパスを指定します。各Redisインスタンスの情報を含むnodes.confファイルを作成します。クラスターを起動し、CREATEコマンドを実行してクラスターを作成し、レプリカの数を指定します。クラスターにログインしてクラスター情報コマンドを実行して、クラスターステータスを確認します。作る

Redisコマンドの使用方法 Redisコマンドの使用方法 Apr 10, 2025 pm 08:45 PM

Redis指令を使用するには、次の手順が必要です。Redisクライアントを開きます。コマンド(動詞キー値)を入力します。必要なパラメーターを提供します(指示ごとに異なります)。 Enterを押してコマンドを実行します。 Redisは、操作の結果を示す応答を返します(通常はOKまたは-ERR)。

Redisデータをクリアする方法 Redisデータをクリアする方法 Apr 10, 2025 pm 10:06 PM

Redisデータをクリアする方法:Flushallコマンドを使用して、すべての重要な値をクリアします。 FlushDBコマンドを使用して、現在選択されているデータベースのキー値をクリアします。 [選択]を使用してデータベースを切り替え、FlushDBを使用して複数のデータベースをクリアします。 DELコマンドを使用して、特定のキーを削除します。 Redis-CLIツールを使用してデータをクリアします。

Redisのソースコードを読み取る方法 Redisのソースコードを読み取る方法 Apr 10, 2025 pm 08:27 PM

Redisソースコードを理解する最良の方法は、段階的に進むことです。Redisの基本に精通してください。開始点として特定のモジュールまたは機能を選択します。モジュールまたは機能のエントリポイントから始めて、行ごとにコードを表示します。関数コールチェーンを介してコードを表示します。 Redisが使用する基礎となるデータ構造に精通してください。 Redisが使用するアルゴリズムを特定します。

単一のスレッドレディスの使用方法 単一のスレッドレディスの使用方法 Apr 10, 2025 pm 07:12 PM

Redisは、単一のスレッドアーキテクチャを使用して、高性能、シンプルさ、一貫性を提供します。 I/Oマルチプレックス、イベントループ、ノンブロッキングI/O、共有メモリを使用して同時性を向上させますが、並行性の制限、単一の障害、および書き込み集約型のワークロードには適していません。

基礎となるRedisを実装する方法 基礎となるRedisを実装する方法 Apr 10, 2025 pm 07:21 PM

Redisはハッシュテーブルを使用してデータを保存し、文字列、リスト、ハッシュテーブル、コレクション、注文コレクションなどのデータ構造をサポートします。 Redisは、スナップショット(RDB)を介してデータを維持し、書き込み専用(AOF)メカニズムを追加します。 Redisは、マスタースレーブレプリケーションを使用して、データの可用性を向上させます。 Redisは、シングルスレッドイベントループを使用して接続とコマンドを処理して、データの原子性と一貫性を確保します。 Redisは、キーの有効期限を設定し、怠zyな削除メカニズムを使用して有効期限キーを削除します。

Redisキューの読み方 Redisキューの読み方 Apr 10, 2025 pm 10:12 PM

Redisのキューを読むには、キュー名を取得し、LPOPコマンドを使用して要素を読み、空のキューを処理する必要があります。特定の手順は次のとおりです。キュー名を取得します:「キュー:キュー」などの「キュー:」のプレフィックスで名前を付けます。 LPOPコマンドを使用します。キューのヘッドから要素を排出し、LPOP Queue:My-Queueなどの値を返します。空のキューの処理:キューが空の場合、LPOPはnilを返し、要素を読む前にキューが存在するかどうかを確認できます。

Redis用のメッセージミドルウェアの作成方法 Redis用のメッセージミドルウェアの作成方法 Apr 10, 2025 pm 07:51 PM

Redisは、メッセージミドルウェアとして、生産消費モデルをサポートし、メッセージを持続し、信頼できる配信を確保できます。メッセージミドルウェアとしてRedisを使用すると、低遅延、信頼性の高いスケーラブルなメッセージングが可能になります。

See all articles