目次
メモリベースの実装
効率的なデータ構造
#SDS 単純な動的文字列
文字列の長さ処理
メモリの再割り当ての回数を減らす
Hash
跳跃表
压缩列表ziplist
合理的数据编码
合理的线程模型
单线程模型:避免了上下文切换
I/O 多路复用
仮想メモリ機構
ホームページ データベース Redis Redis がなぜこれほど速いのかを詳しく分析しますか?

Redis がなぜこれほど速いのかを詳しく分析しますか?

Sep 16, 2021 pm 07:46 PM
redis

Redis がなぜこれほど速いのかを詳しく分析しますか?

Redis が非常に高速で、その QPS が 100,000 (1 秒あたりのリクエスト) に達する可能性があることは誰もが知っています。 なぜ Redis はこんなに速いのですか?、この記事で皆さんと一緒に学びましょう。 [関連する推奨事項: Redis ビデオ チュートリアル ]

Redis がなぜこれほど速いのかを詳しく分析しますか?

メモリベースの実装

メモリの読み取りと書き込みが、他の実装よりも高速であることは誰もが知っています。ディスクの読み書きがたくさんあります。 Redis はメモリ ストレージをベースに実装されたデータベースであり、データがディスクに保存されるデータベースと比較して、ディスク I/O の消費がありません。 MySQL などのディスク データベースでは、クエリの効率を高めるためにインデックスを作成する必要がありますが、Redis データはメモリに保存され、メモリ上で直接動作するため、非常に高速です。

Redis がなぜこれほど速いのかを詳しく分析しますか?

効率的なデータ構造

効率を向上させるために、MySQL インデックスは B ツリー データ構造を選択することがわかっています。実際、合理的なデータ構造により、アプリケーション/プログラムを高速化できます。まず、Redis のデータ構造と内部エンコード図を見てみましょう。

Redis がなぜこれほど速いのかを詳しく分析しますか?

#SDS 単純な動的文字列

Redis がなぜこれほど速いのかを詳しく分析しますか?

#
struct sdshdr { //SDS简单动态字符串
    int len;    //记录buf中已使用的空间
    int free;   // buf中空闲空间长度
    char buf[]; //存储的实际内容
}
ログイン後にコピー

文字列の長さ処理

C言語では、文字列カタツムリを拾う小さな男の子の長さを取得するには、それを最初からたどる必要があり、複雑さはO(n)です。 Redis には、現在の文字列の長さを記録する len フィールドがすでにあり、これを直接取得でき、時間計算量は O(1) です。

メモリの再割り当ての回数を減らす

C 言語では、文字列を変更するにはメモリの再割り当てが必要です。変更の頻度が高くなるほど、メモリの割り当ても頻繁になり、メモリの割り当ては 消費パフォーマンス。 Redis では、SDS は、スペースの事前割り当てと遅延スペースの解放という 2 つの最適化戦略を提供します。

スペースの事前割り当て

SDS の単純な動的文字列の変更とスペースの拡張では、必要なメモリ スペースの割り当てに加えて、追加の未使用スペースが割り当てられます。割り当てルールは紫色です:

  • SDS が変更された後、len の長さが 1M 未満になり、len と同じ長さの追加の未使用スペースが割り当てられます。たとえば、len=100 の場合、再割り当て後の buf の実際の長さは、100 (使用済みスペース) 100 (余分なスペース) 1 (ヌル文字) = 201 になります。
  • SDS が変更された後、len の長さが 1M より大きい場合、プログラムは 1M の未使用スペースを割り当てます。

遅延領域解放

SDS が短縮されると、余分なメモリ領域を再利用する代わりに、free を使用して余分な領域が記録されます。後続の変更操作がある場合は、空き領域が直接使用されてメモリ割り当てが削減されます。

Hash

Redis は K-V インメモリ データベースであり、グローバル ハッシュを使用してすべてのキーと値のペアを保存します。このハッシュ テーブルは複数のハッシュ バケットで構成されており、ハッシュ バケット内のエントリ要素には *key*value ポインタが格納されており、そのうち *key は実際のキー、*value は実際の値を指します。

Redis がなぜこれほど速いのかを詳しく分析しますか?

ハッシュ テーブルの検索速度は非常に速く、Java の HashMap に似ており、O(1)# を実行できます。 ## キーと値のペアを素早く見つけるのにかかる時間の複雑さ。まず、キーを通じてハッシュ値を計算し、対応するハッシュ バケットの場所を見つけて、次にエントリを見つけて、エントリ内の対応するデータを見つけます。

友人の中には、こんな疑問を持つ人もいるかもしれません。大量のデータをハッシュ テーブルに書き込むと、

ハッシュ競合 問題が発生し、効率が低下するのではないかということです。

ハッシュの競合: 同じハッシュ値が異なるキーを通じて計算され、結果として同じハッシュ バケットが生成されます。

ハッシュの競合を解決するために、Redis は

チェーン ハッシュ を使用します。連鎖ハッシュとは、同じハッシュ バケット内の複数の要素がリンク リストに格納され、ポインタを使用して順番に接続されることを意味します。

Redis がなぜこれほど速いのかを詳しく分析しますか?

#まだ疑問を持っている友人もいるかもしれません。ハッシュ競合チェーン上の要素は、ポインターを介して 1 つずつ検索して操作することしかできません。大量のデータがハッシュ テーブルに挿入されると、競合が多くなり、競合リンク リストが長くなり、クエリの効率が低下します。

効率を維持するために、Redis はハッシュ テーブルに対して

再ハッシュ操作 を実行します。これは、ハッシュ バケットを追加して競合を減らすことを意味します。再ハッシュをより効率的にするために、Redis はデフォルトで 2 つのグローバル ハッシュ テーブルも使用します。1 つはメイン ハッシュ テーブルと呼ばれる現在使用用で、もう 1 つは拡張用でありバックアップ ハッシュ テーブルと呼ばれます。

跳跃表

跳跃表是Redis特有的数据结构,它其实就是在链表的基础上,增加多级索引,以提高查找效率。跳跃表的简单原理图如下:

Redis がなぜこれほど速いのかを詳しく分析しますか?

  • 每一层都有一条有序的链表,最底层的链表包含了所有的元素。
  • 跳跃表支持平均 O(logN),最坏 O(N)复杂度的节点查找,还可以通过顺序性操作批量处理节点。

压缩列表ziplist

压缩列表ziplist是列表键和字典键的的底层实现之一。它是由一系列特殊编码的内存块构成的列表, 一个ziplist可以包含多个entry, 每个entry可以保存一个长度受限的字符数组或者整数,如下:

Redis がなぜこれほど速いのかを詳しく分析しますか?

  • zlbytes :记录整个压缩列表占用的内存字节数
  • zltail: 尾节点至起始节点的偏移量
  • zllen : 记录整个压缩列表包含的节点数量
  • entryX: 压缩列表包含的各个节点
  • zlend : 特殊值0xFF(十进制255),用于标记压缩列表末端

由于内存是连续分配的,所以遍历速度很快。。

合理的数据编码

Redis支持多种数据基本类型,每种基本类型对应不同的数据结构,每种数据结构对应不一样的编码。为了提高性能,Redis设计者总结出,数据结构最适合的编码搭配。

Redis是使用对象(redisObject)来表示数据库中的键值,当我们在 Redis 中创建一个键值对时,至少创建两个对象,一个对象是用做键值对的键对象,另一个是键值对的值对象。

//关注公众号:捡田螺的小男孩
typedef struct redisObject{
    //类型
   unsigned type:4;
   //编码
   unsigned encoding:4;
   //指向底层数据结构的指针
   void *ptr;
    //...
 }robj;
ログイン後にコピー

redisObject中,type 对应的是对象类型,包含String对象、List对象、Hash对象、Set对象、zset对象。encoding 对应的是编码。

  • String:如果存储数字的话,是用int类型的编码;如果存储非数字,小于等于39字节的字符串,是embstr;大于39个字节,则是raw编码。
  • List:如果列表的元素个数小于512个,列表每个元素的值都小于64字节(默认),使用ziplist编码,否则使用linkedlist编码
  • Hash:哈希类型元素个数小于512个,所有值小于64字节的话,使用ziplist编码,否则使用hashtable编码。
  • Set:如果集合中的元素都是整数且元素个数小于512个,使用intset编码,否则使用hashtable编码。
  • Zset:当有序集合的元素个数小于128个,每个元素的值小于64字节时,使用ziplist编码,否则使用skiplist(跳跃表)编码

合理的线程模型

单线程模型:避免了上下文切换

Redis是单线程的,其实是指Redis的网络IO和键值对读写是由一个线程来完成的。但Redis的其他功能,比如持久化、异步删除、集群数据同步等等,实际是由额外的线程执行的。

Redis的单线程模型,避免了CPU不必要的上下文切换竞争锁的消耗。也正因为是单线程,如果某个命令执行过长(如hgetall命令),会造成阻塞。Redis是面向快速执行场景的内存数据库,所以要慎用如lrange和smembers、hgetall等命令。

什么是上下文切换?举个粟子:

  • 比如你在看一本英文小说,你看到某一页,发现有个单词不会读,你加了个书签,然后去查字典。查完字典后,你回来从书签那里继续开始读,这个流程就很舒畅。
  • 如果你一个人读这本书,肯定没啥问题。但是如果你去查字典的时候,别的小伙伴翻了一下你的书,然后溜了。你再回来看的时候,发现书不是你看的那一页了,你得花时间找到你的那一页。
  • 一本书,你一个人怎么看怎么打标签都没事,但是人多了翻来翻去,这本书各种标记就很乱了。可能这个解释很粗糙,但是道理应该是一样的。

Redis がなぜこれほど速いのかを詳しく分析しますか?

I/O 多路复用

什么是I/O多路复用?

  • I/O: ネットワーク I/O
  • マルチチャネル: 複数のネットワーク接続
  • 多重化: 同じスレッドを多重化します。
  • IO 多重化は実際には同期 IO モデルであり、複数のファイル ハンドルを監視できるスレッドを実装します。ファイル ハンドルの準備が完了すると、対応する読み取りおよび書き込み操作を実行するようにアプリケーションに通知できます。ファイル ハンドルがない場合は、準備ができている場合、アプリケーションはブロックされ、CPU が引き渡されます。

Redis がなぜこれほど速いのかを詳しく分析しますか?

複数の I/O 多重化テクノロジにより、単一のスレッドで複数の接続リクエストを効率的に処理できます。Redis は、I/O として epoll を使用します。多重化テクノロジの実装。さらに、Redis 独自のイベント処理モデルは、ネットワーク I/O にあまり時間を費やすことなく、epoll での接続、読み取り、書き込み、および終了をイベントに変換します。

仮想メモリ機構

Redis は VM 機構を自ら直接構築するため、通常のシステムのようにシステム関数を呼び出したり、移動やリクエストに一定の時間を浪費したりすることはありません。

Redis の仮想メモリ メカニズムとは何ですか?

仮想メモリ メカニズムは、アクセス頻度の低いデータ (コールド データ) をメモリからディスクに一時的に交換し、アクセスする必要がある他のデータ (ホット データ) のために貴重なメモリ領域を解放します。 。 データ)。 VM 機能は、ホット データとコールド データの分離を実現できるため、ホット データはメモリ内に残り、コールド データはディスクに保存されます。これにより、メモリ不足によるアクセス速度の低下の問題を回避できます。

プログラミング関連の知識について詳しくは、プログラミング ビデオをご覧ください。 !

以上が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衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の 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 10:06 PM

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

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

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

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

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

Redisロックの使用方法 Redisロックの使用方法 Apr 10, 2025 pm 08:39 PM

Redisを使用して操作をロックするには、setnxコマンドを介してロックを取得し、有効期限を設定するために有効期限コマンドを使用する必要があります。特定の手順は次のとおりです。(1)SETNXコマンドを使用して、キー価値ペアを設定しようとします。 (2)expireコマンドを使用して、ロックの有効期限を設定します。 (3)Delコマンドを使用して、ロックが不要になったときにロックを削除します。

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

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

Redisコマンドラインの使用方法 Redisコマンドラインの使用方法 Apr 10, 2025 pm 10:18 PM

Redisコマンドラインツール(Redis-Cli)を使用して、次の手順を使用してRedisを管理および操作します。サーバーに接続し、アドレスとポートを指定します。コマンド名とパラメーターを使用して、コマンドをサーバーに送信します。ヘルプコマンドを使用して、特定のコマンドのヘルプ情報を表示します。 QUITコマンドを使用して、コマンドラインツールを終了します。

Centos RedisでLUAスクリプト実行時間を構成する方法 Centos RedisでLUAスクリプト実行時間を構成する方法 Apr 14, 2025 pm 02:12 PM

Centosシステムでは、Redis構成ファイルを変更するか、Redisコマンドを使用して悪意のあるスクリプトがあまりにも多くのリソースを消費しないようにすることにより、LUAスクリプトの実行時間を制限できます。方法1:Redis構成ファイルを変更し、Redis構成ファイルを見つけます:Redis構成ファイルは通常/etc/redis/redis.confにあります。構成ファイルの編集:テキストエディター(VIやNANOなど)を使用して構成ファイルを開きます:sudovi/etc/redis/redis.conf luaスクリプト実行時間制限を設定します。

See all articles