ホームページ  >  記事  >  バックエンド開発  >  golang は redis を実装します

golang は redis を実装します

王林
王林オリジナル
2023-05-22 17:12:441281ブラウズ

Redis は、非常に人気のある高性能のキー/値ストレージ データベースであり、キャッシュ、メッセージ キュー、データ ストレージなどのシナリオで広く使用されています。この記事では、Go 言語を使用して簡単な Redis データベースを実装する方法を紹介します。

Redis データ構造

Redis は、キーと値の両方をさまざまなデータ型にすることができるキー/値ストレージ データベースです。 Redis は 5 つの基本データ型をサポートします:

  1. String: Redis の最も基本的なデータ型です。文字列型はバイナリ セーフです。つまり、あらゆるデータを含めることができます。最大データ長は 512 MB です。
  2. List (リスト): リスト タイプは二重リンク リストで、各ノードには文字列が含まれており、リストの両端でハング、移動、ポップなどの操作が可能です。
  3. Set: セット タイプは、重複しない一意の文字列を含む、順序付けされていないコレクションです。
  4. ハッシュ テーブル (ハッシュ): ハッシュ テーブル タイプは、文字列フィールドと対応する値を含む順序付けされていないハッシュ テーブルです。文字列フィールドは一意であり、キーと値のペアを格納するために使用されます。
  5. 順序付きセット (ZSet): 順序付きセット タイプは、重複しない一意のメンバーと各メンバーに関連付けられた順序付きスコアを含むランク付けされていない順序付きセットです。

上記のデータ型の中で、最も一般的に使用される型は、文字列、リスト、ハッシュ テーブル、および順序付きセットです。

他のデータベースとは異なり、Redis はパフォーマンス上の理由からシングルスレッド モデルを使用し、大量のメモリを使用するため、データを頻繁にディスクに書き込む必要があります。

Redis コマンド

Redis コマンド (コマンド) は、クライアントから Redis サーバーに送信されるメッセージで、通常はプレーン テキスト形式であり、コマンドとパラメーターの間の区切り文字として
を使用します。シンボル。各コマンドは 1 つ以上のパラメータで構成され、最初のパラメータはコマンド名です。 Redis コマンドを使用すると、データの読み取りと書き込み、キーの作成と削除など、Redis データベース内のデータを操作できます。

次に、一般的に使用されるコマンドの例をいくつか示します。

  1. SET: キーと値のペアを設定します。

    set key value

  2. GET: 指定されたキーの値を取得します。

    get key

  3. INCR: 指定されたキーの値を 1 増やします。

    incr key

  4. DECR: 指定されたキーの値を 1 減らします。

    decr key

  5. EXPIRE: キーの有効期限を設定します。

    expire key minutes

Redis データベースの実装

Redis データベースを実装するには、5 種類のデータ構造 : 文字列、リスト、セット、ハッシュ テーブル、およびソートされたセット。また、クライアント コマンドを受け入れて処理できるように、Redis サーバーを実装する必要があります。

最初に、すべてのキーと値のペアを保存でき、5 種類のデータ構造を含む Redis データベース構造を定義する必要があります。

type RedisDB struct {
   StringData map[string]string
   ListData map[string][]string
   SetData map[string]map[string]bool
   HashData map[string]map[string]string
   ZsetData map[string]map[string]float64
}

次に、Redis コマンド メソッドの処理を定義します。 。 switch ステートメントを使用して、コマンド名ごとに case ステートメントを記述し、コマンド名とパラメーターに基づいて対応するメソッドにディスパッチできます。たとえば、次のようになります。

func (r *RedisDB) ExecuteCommand(command []string) interface{} {
   switch strings.ToLower(command[0]) {
   case "get":
      return r.Get(command[1])
   case "set":
      r.Set(command[1], command[2])
      return "OK"
   case "del":
      r.Del(command[1:]...)
      return "OK"
   case "exists":
      return r.Exists(command[1])
   case "expire":
      r.Expire(command[1], command[2])
      return "OK"
   }
   return fmt.Sprintf("Error: unknown command %s", command[0])
}

各コマンドを処理するメソッドを実装する必要があります。 Redisコマンド。たとえば、GET コマンドの実装は次のとおりです。

func (r *RedisDB) Get(key string) interface{} {
   result, ok := r.StringData[key]
   if !ok {
      return nil
   }
   return result
}

SET コマンドの実装は次のとおりです。

func (r *RedisDB) Set(key, value string) {
   r.StringData[key] = value
}

DEL コマンドの実装は次のとおりです。

func (r *RedisDB) Del(keys ...string) {
   for i := range keys {
      delete(r.StringData, keys[i]) // 删除字符串
      delete(r.ListData, keys[i])   // 删除列表
      delete(r.SetData, keys[i])    // 删除集合
      delete(r.HashData, keys[i])   // 删除哈希表
      delete(r.ZsetData, keys[i])   // 删除有序集合
   }
}

EXISTS コマンドは次のとおりです。

func (r *RedisDB) Exists(key string) interface{} {
   _, ok1 := r.StringData[key]
   _, ok2 := r.ListData[key]
   _, ok3 := r.SetData[key]
   _, ok4 := r.HashData[key]
   _, ok5 := r.ZsetData[key]
   if ok1 || ok2 || ok3 || ok4 || ok5 {
      return true
   }
   return false
}

最後に、クライアントからコマンドを受け取り、データベースのコマンド処理メソッドに渡して結果を取得する、Redis データベース用の単純なコマンド パーサーを実装しました。コードは次のとおりです。

func (r *RedisDB) CommandParser(conn net.Conn) {
   defer conn.Close()
   reader := bufio.NewReader(conn)
   for {
      command, err := reader.ReadString('
')
      if err != nil {
         return
      }
      command = strings.TrimRight(command, "
")
      if len(command) == 0 {
         continue
      }

      args := strings.Split(command, " ")
      result := r.ExecuteCommand(args)
      data, _ := json.Marshal(result)
      conn.Write(data)
      conn.Write([]byte("
"))
   }
}

このようにして、単純な Redis データベースを実装しました。

Redis データベースをテストする

Telnet を使用して Redis データベースをテストできます。まず、Redis サーバーを実行します:

redis := RedisDB{
   StringData: make(map[string]string),
   ListData: make(map[string][]string),
   SetData: make(map[string]map[string]bool),
   HashData: make(map[string]map[string]string),
   ZsetData: make(map[string]map[string]float64),
}
listener, err := net.Listen("tcp", ":6379")
if err != nil {
   log.Fatal("Unable to listen on port 6379", err)
}
for {
   conn, err := listener.Accept()
   if err != nil {
      log.Println("Error accepting connection", err)
      continue
   }
   go redis.CommandParser(conn)
}

次に、telnet を使用して Redis サーバーに接続します:

telnet localhost 6379

telnet でコマンドを入力して、Redis データベースをテストします:

set name john
OK
get name
"john"
exists name
true
expire name 60
OK
del name
OK

このようにして、シンプルな Redis データベースを実装することに成功しました。もちろん、これは単なる基本的な実装であり、実際の Redis データベースには、パブリッシュ/サブスクライブ、Lua スクリプト、トランザクション、永続性、クラスタリングなどの多くの高度な機能も含まれています。ただし、この記事で提供されている簡単なバージョンは、Redis の基本的な実装原則を理解するのに十分です。

以上がgolang は redis を実装しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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