GoによるRedisの5永続化
前に書く
本明細書で実装Godisコードのバージョンは、v 0である.1
Redis持続化方式
RDB持続化
BGSAVEとSAVEコマンドはRDBファイルを生成し、データベース情報を格納する.サーバが起動すると、RDBファイルも元のデータとして近サービスメモリをロードします.ここでは、AOFの永続化がオンの場合、AOFファイルからのデータのロード、データベースの状態の復元が優先されるという優先順位の問題があります.
SAVEコマンドはサービスをブロックしますが、BGSAVEは独立したプロセスを派生し、ブロックしません.また、オプション構成によってRDBの永続化を自動的に実行するサイクルを設定することもできます.
Redisサービス側は、最初に述べたserver.dirtyフィールドのようないくつかのパラメータを記録することによって、前回のSAVE後にデータベースの変更が何回行われたかを記録します.定期的なバックグラウンド操作serverConが実行されると、データベースの更新ステータスがRDB永続化条件を満たしているかどうかを確認し、データベースステータスを保存します.注意:RDBのファイルはデータベースデータのストレージに対して、キー値ペアを格納する方法を採用しています.
AOF持続化
前述したRDBファイルは、データそのものを保存し、AOFファイルは、実行されたコマンドから変換されたプロトコルを格納する.RedisのAOF永続化をオンにして、いくつかのコマンドを操作した後、
AOF永続化が変更コマンドごとにファイルに計上されると、無効なコマンドが記録されます.次のようになります.
4つのコマンドはプロシージャであり、データベースレコードの最終値123がプロシージャの最終結果である.同一キーの操作に対する「無効コマンド」の記録を避けるため、Redisには、AOFファイルに追加するコマンドレコードとして現在のデータ状態を読み出すAOF書き換え機構がある.
GodisによるAOF持続化
GodisはAOF永続化のみを実現し,コマンドの書き換え集計操作は行わず,すべての修正操作がAOFファイルに記録される.これは、データ保存段階において、無効なI/O操作が多くなることを意味する.ロードフェーズでは、無効なコマンドが多数実行されます.
ディスクへのデータの永続化
Godisの符号化にはRedisのようなイベントループは用いられておらず,ここではserverに依存する.dirtyフィールドを識別します.dirty変化は持続化のタイミングである.
まず、コマンド呼び出しにAOF永続化判定を追加し、dirtyが変化すると永続化を行う.
永続化操作を実行する関数AppendToFileも簡単で、ファイルに書き込みを追加し、すぐに閉じます.
最後に、
効果をテストしてgodis-serverを再コンパイルします.go、
ファイルにコマンドプロトコルが正常に書き込まれました.
サービス起動ロードデータ
永続化されたデータをファイルからメモリにロードする方法は、クライアント実行コマンドをシミュレートし、AOFファイルコマンドをサービス側に1本ずつ送信することです.
core.ReadAofはAOFファイルをメモリに読み込み、ストライプで格納します.その後のProcessCommandはset/getコマンド実装で紹介され、説明されません.
統合テスト
サービス側を閉じ、サービス側を再起動し、クライアントで
AOFファイルをチェックして、コマンドgetに関するレコードを読みませんでした.
本編の問題
疑似クライアントが実行する時、持久化操作を実行しないで、Client構造に対して疑似端末フラグビットを増加して、持久化判断に用いる:
小結
次回の予告はありません.この5つの短文の初志はGOを学ぶ際に書かれた小さなdemoを記録することであり、結果的に他の言語に費やされるまでの精力が予算を超えたため、その後もGodisの新しいfeatureを開発し続けることはなかった.
明日会社の仕事で忙しいプロジェクトの改造期间を迎えて、今日の端午の节句の小连休の最后の日に乗じて、V 0を理解しました.1バージョン.しかし、近い将来、次の連休には、前述したkeyの期限切れ、ネットワーク最適化、API開発、Streamなどの新しいfeatureと最適化が公開されるかもしれません.討論を歓迎する.
本明細書で実装Godisコードのバージョンは、v 0である.1
Redis持続化方式
RDB持続化
BGSAVEとSAVEコマンドはRDBファイルを生成し、データベース情報を格納する.サーバが起動すると、RDBファイルも元のデータとして近サービスメモリをロードします.ここでは、AOFの永続化がオンの場合、AOFファイルからのデータのロード、データベースの状態の復元が優先されるという優先順位の問題があります.
SAVEコマンドはサービスをブロックしますが、BGSAVEは独立したプロセスを派生し、ブロックしません.また、オプション構成によってRDBの永続化を自動的に実行するサイクルを設定することもできます.
Redisサービス側は、最初に述べたserver.dirtyフィールドのようないくつかのパラメータを記録することによって、前回のSAVE後にデータベースの変更が何回行われたかを記録します.定期的なバックグラウンド操作serverConが実行されると、データベースの更新ステータスがRDB永続化条件を満たしているかどうかを確認し、データベースステータスを保存します.注意:RDBのファイルはデータベースデータのストレージに対して、キー値ペアを格納する方法を採用しています.
AOF持続化
前述したRDBファイルは、データそのものを保存し、AOFファイルは、実行されたコマンドから変換されたプロトコルを格納する.RedisのAOF永続化をオンにして、いくつかのコマンドを操作した後、
appendonly.aof
ファイルを参照してください.データのバックアップ操作なので、読み取りコマンドは記録する必要はなく、修正型の操作を記録するだけです.AOF永続化が変更コマンドごとにファイルに計上されると、無効なコマンドが記録されます.次のようになります.
set alpha 123
set alpha 1
set alpha 321
set alpha 123
4つのコマンドはプロシージャであり、データベースレコードの最終値123がプロシージャの最終結果である.同一キーの操作に対する「無効コマンド」の記録を避けるため、Redisには、AOFファイルに追加するコマンドレコードとして現在のデータ状態を読み出すAOF書き換え機構がある.
GodisによるAOF持続化
GodisはAOF永続化のみを実現し,コマンドの書き換え集計操作は行わず,すべての修正操作がAOFファイルに記録される.これは、データ保存段階において、無効なI/O操作が多くなることを意味する.ロードフェーズでは、無効なコマンドが多数実行されます.
ディスクへのデータの永続化
Godisの符号化にはRedisのようなイベントループは用いられておらず,ここではserverに依存する.dirtyフィールドを識別します.dirty変化は持続化のタイミングである.
まず、コマンド呼び出しにAOF永続化判定を追加し、dirtyが変化すると永続化を行う.
func call(c *Client, s *Server) {
dirty := s.Dirty
c.Cmd.Proc(c, s)
dirty = s.Dirty - dirty
if dirty > 0 {//dirty
AppendToFile(s.AofFilename, c.QueryBuf)
}
}
永続化操作を実行する関数AppendToFileも簡単で、ファイルに書き込みを追加し、すぐに閉じます.
func AppendToFile(fileName string, content string) error {
// ,
f, err := os.OpenFile(fileName, os.O_WRONLY|syscall.O_CREAT, 0644)
if err != nil {
log.Println("log file open failed" + err.Error())
} else {
n, _ := f.Seek(0, os.SEEK_END)
_, err = f.WriteAt([]byte(content), n)
}
defer f.Close()
return err
}
最後に、
set
命令のような修正型命令の実装において、serverを追加する.dirtyの更新.func SetCommand(c *Client, s *Server) {
···
s.Dirty++
···
}
効果をテストしてgodis-serverを再コンパイルします.go、
set alpha 123
を実行します.ファイルにコマンドプロトコルが正常に書き込まれました.
サービス起動ロードデータ
永続化されたデータをファイルからメモリにロードする方法は、クライアント実行コマンドをシミュレートし、AOFファイルコマンドをサービス側に1本ずつ送信することです.
func LoadData() {
c := godis.CreateClient()
pros := core.ReadAof(godis.AofFilename)
for _, v := range pros {
c.QueryBuf = string(v)
err := c.ProcessInputBuffer()
if err != nil {
log.Println("ProcessInputBuffer err", err)
}
godis.ProcessCommand(c)
}
}
core.ReadAofはAOFファイルをメモリに読み込み、ストライプで格納します.その後のProcessCommandはset/getコマンド実装で紹介され、説明されません.
統合テスト
サービス側を閉じ、サービス側を再起動し、クライアントで
get alpha
を直接実行し、前のsetの値を取得できるかどうかを確認します.AOFファイルをチェックして、コマンドgetに関するレコードを読みませんでした.
本編の問題
疑似クライアントが実行する時、持久化操作を実行しないで、Client構造に対して疑似端末フラグビットを増加して、持久化判断に用いる:
func LoadData() {
c := godis.CreateClient()
c.FakeFlag = true
···
}
小結
次回の予告はありません.この5つの短文の初志はGOを学ぶ際に書かれた小さなdemoを記録することであり、結果的に他の言語に費やされるまでの精力が予算を超えたため、その後もGodisの新しいfeatureを開発し続けることはなかった.
明日会社の仕事で忙しいプロジェクトの改造期间を迎えて、今日の端午の节句の小连休の最后の日に乗じて、V 0を理解しました.1バージョン.しかし、近い将来、次の連休には、前述したkeyの期限切れ、ネットワーク最適化、API開発、Streamなどの新しいfeatureと最適化が公開されるかもしれません.討論を歓迎する.