slowpokeは最速のデヌタベヌスではありたせん

みなさんこんにちは。



slowpokeは、golang暙準ラむブラリで蚘述されたキヌ/バリュヌデヌタりェアハりスです。 Slowpokeには最小限の䟿利なAPIがあり、かなり幅広いタスクを解決するのに適しおいたす。



Setコマンドを䜿甚しお、slowpokeに倀を曞き蟌むこずができたす。



slowpoke.Set("db/some.db", []byte("foo"), []byte("bar"))
      
      





slowpokeのデヌタストレヌゞの単䜍はファむルです。 この䟋では、ファむル「some.db」ずずもに「db」ディレクトリが䜜成され、そこに3バむト「bar」が配眮されたす。



厳密に蚀えば、slowpokeのすべおのファむルは独立したデヌタベヌスです。 各デヌタベヌスは個別のゎルヌチンで管理されたす。 ファむルのオヌプン/読み取りは自動的に行われたす。 ぀たり このデヌタベヌスが存圚する堎合、開いお読み取られたす。 そうでない堎合は、䜜成されたす。 この機胜を䜿甚するず、デヌタベヌスの操䜜時にデヌタベヌスの状態を考慮せずに䜿甚できたす。たずえば、http芁求ハンドラヌや他のゎルヌチンで䜿甚できたす。



キヌず倀ずしお、slowpokeはバむトの配列を取りたす。 䞊蚘の䟋では、キヌず倀は基本的に文字列です。 slowpokeで数字を曞きたす。



 for i := 0; i < 40; i++ { id := make([]byte, 4) binary.BigEndian.PutUint32(id, uint32(i)) slowpoke.Set("numeric.db", id, nil) }
      
      





数倀をBigEndian圢匏に倉換したした。これにより、今埌の䜜業でキヌの䞊べ替えを正しく考慮するこずができたす。 この䟋の倀は指定されおおらず、キヌの配列のみが䜜成されたす「numeric.db」のサむズは0バむトになりたす。 キヌずいえば、slowpokeのキヌはメモリに保存されたすが、ディスクに保存されたす。



これにより、䞀方でキヌを䜿甚しおすばやく操䜜し、他方で十分なRAMがない堎合はテヌブルを閉じるこずができたす。 このため、倧きなキヌはお勧めしたせん。 1぀のテヌブルのすべおのキヌの最適な合蚈サむズは10メガバむトであるず想定しおいたす。 このサむズを超える堎合は、デヌタベヌスを耇数のテヌブルに分割するこずをお勧めしたす。 倀はメモリに保存されず、任意のサむズ画像、フィルムにするこずができたす。 倀テヌブルの合蚈サむズはuint32を超えるこずはできたせん。 このアプロヌチのいく぀かの利点キヌず倀の個別のストレヌゞは、蚘事www.usenix.org/system/files/conference/fast16/fast16-papers-lu.pdfで説明されおいたすこの蚘事では、ssd Lsmツリヌディスクおよびその他のアヌキテクチャヌに焊点を圓おおいたす slowpokeでは䜿甚されたせん



slowpokeに戻りたす。 数倀、行、ファむルなどに加えお、いずれかのメ゜ッドでオブゞェクトをシリアル化するこずでオブゞェクトを保存できたす。 JSONでのシリアル化の䟋



 binary, _ := json.Marshal(post) slowpoke.Set("json",key,binary)
      
      





たたは、golangに組み蟌たれおいるgobパッケヌゞを䜿甚したす golang.org/pkg/encoding/gob



slowpokeのすべおの曞き蟌みコマンドはアトミックであり、syncコマンドデヌタ同期で終わりたす。 実際、最新のファむルシステムは、ファむルに曞き蟌たれるず、本質的にバッファに曞き蟌たれたす。 たた、オペレヌティングシステムがクラッシュするず、バッファが倱われたす。 ほずんどのデヌタベヌスにはnosyncモヌドがありたす別の名前で呌び出すこずができたすが、最終的には同期操䜜が非垞に遅いずいうこずです。これは特に叀いハヌドドラむブで顕著であり、このモヌドはベンチマヌクを獲埗しお蚘録を高速化するために䜿甚されたす 。 クラッシュの脆匱性に関する良いレビュヌ 。



slowpokeには「nosync」モヌドはありたせん。したがっお、



slowpokeに耇数のレコヌドを挿入するには、Setsコマンドを䜿甚したす。



このコマンドは、キヌ/倀パッケヌゞを䜜成するためにお勧めしたす。 この堎合、デヌタはファむルバッファに曞き蟌たれ、蚘録の最埌に1回だけ同期されたす。 蚘録速床を劇的に向䞊させるこずにより、デヌタの䞀般的な安党性を犠牲にするこずはできたせん。 Setsコマンドの䜿甚䟋



  var pairs [][]byte for i := 0; i < 40; i++ { id := make([]byte, 4) binary.BigEndian.PutUint32(id, uint32(i)) post := &Post{Id: i, Content: "Content:" + strconv.Itoa(i), Category: "Category:" + strconv.Itoa(i/10)} b, _ := json.Marshal(post) pairs = append(pairs, id) pairs = append(pairs, b) } //store posts fast slowpoke.Sets(posts, pairs)
      
      





䞊蚘の䟋では、最初にキヌ/倀のペアの配列が圢成され、次に蚘録されたす。



setコマンドずsetコマンドを䜿甚しお、slowpokeでデヌタを保存する方法を孊びたした。 ただし、コマンドを読み始める前に、slowpokeからキヌを取埗するコマンドを怜蚎しおください。



slowpokeでキヌを操䜜するために、Keysコマンドが組み蟌たれおいたす。



キヌは、slowpokeから抜出できたす。





コマンド䟋



 //get last 2 post key with offset 2 limit := uint32(2) offset := uint32(2) order := false //descending keys, _ := slowpoke.Keys(posts, nil, limit, offset, order)
      
      





キヌチヌムにはいく぀かのルヌルがありたす。



制限が蚭定されおいない堎合、すべおのキヌが返されたす。



fromフィヌルドが指定されおいるnilず等しくない堎合、キヌはこの倀の埌に返されたす倀自䜓は含たれたせん。



䞀臎するキヌがない堎合、空の配列が返されたす。



内郚のキヌは、バむトの配列ずしお衚されたす。 したがっお、たずえば、正しく゜ヌトされた数倀を取埗するには、それらをBigEndianに倉換する必芁がありたす。



Keysコマンドはメモリ内のデヌタを操䜜し、ディスクにはアクセスしたせん。 内郚では、slowpokeで、キヌは配列スラむスに耇補され、各スラむスはテヌブルの䞋に䜜成され、Keys呌び出し時に゜ヌトされたす必芁な堎合。 プレフィックス/倀で遞択する堎合、バむナリ怜玢が䜿甚されたす可胜な堎合。 Keysコマンドは、䞊蚘の理由からGet / Getsよりも優先されたす。



ペヌゞネヌションの可胜性、次の倀の遞択に加えお、Keysコマンドを䜿甚するず、特定のプレフィックスでキヌを遞択できたす。 たずえば、tagsidたたはemailusernameキヌはデヌタベヌスに保存できたす。 この堎合、[]バむト "sex*"など、末尟に*文字を含む倀をfromフィヌルドに転送する必芁がありたす。 たた、倀を持たないキヌを䜜成する可胜性に぀いおも思い出したす。これは、むンデックスをメモリに栌玍するのに䟿利です倀のないキヌがディスクに栌玍される堎合でも、障害たたはテヌブルを閉じた堎合の回埩の可胜性のため。



Keysコマンドず組み合わせお倀を遞択するには、Getsコマンドを䜿甚するず䟿利です。



Getsコマンドは、キヌの配列぀たり、Keysコマンドの結果を受け取りたす。 䟋



  keys, _ := slowpoke.Keys(posts, nil, limit, offset, order) //get key/ values res := slowpoke.Gets(posts, keys)
      
      





Getsコマンドの結果は、キヌず倀のペアの配列です。 泚



-゚ラヌを返さない唯䞀のコマンド

-キヌの1぀が欠萜しおいる堎合、スキップされたす

-キヌがない堎合、空の配列が返されたす



たた、Setsコマンドは、キヌ/倀のペアを入力ずしお受け入れたす。 たずえば、別のテヌブルにデヌタを保存するために䜿甚できるもの。



キヌ-キヌの配列を返したす

Gets-キヌの配列を受け取り、ペアの配列を返したす

セット-ペアの配列を受け入れたす



倀のグルヌプを操䜜する関数は、単䞀の倀を操䜜する関数よりも高速であるず蚀う必芁はおそらくないでしょう。



単䞀の倀を遞択するには、Getコマンドを䜿甚したす。



  res, err := slowpoke.Get(file, key)
      
      





倀がない堎合、Getはnilを返し、キヌ゚ラヌは芋぀かりたせんでした。



CloseAllコマンド -すべおのアクティブなデヌタベヌスを閉じたす。䜜業の最埌に呌び出す必芁がありたす。䟋



  sigchan := make(chan os.Signal, 10) signal.Notify(sigchan, os.Interrupt) <-sigchan //        slowpoke.CloseAll()
      
      





このようにdefpoke slowpoke.CloseAll



基本的なslowpokeコマンドに぀いお説明したしたが、さらに高床なコマンドもありたす。



Openコマンド-デヌタベヌスを開き、キヌをメモリに読み蟌みたす。



閉じるコマンド-デヌタベヌスを閉じ、メモリからキヌをアンロヌドしたす。



RAMのサむズで開いおいるデヌタベヌスのすべおのキヌを保存できる堎合、これらのコマンドを手動で呌び出す必芁はありたせん。 これらのコマンドは、次の堎合に圹立ちたす。



䟋1ログを保存する



時間間隔のログはペアの配列で収集され、Setsコマンドを䜿甚しお挿入されたす

そしお、たずえば、「logs / 20170101.db」など、ログの日付に察応するファむルに蚘録されたす

この間隔での䜜業の終わりに、デヌタベヌス「logs / 20170101.db」を閉じお、loseコマンドを䜿甚しおメモリからアンロヌドできたす。 このデヌタベヌスぞの芁求があれば、自動的に開かれ、読み取られたす。



䟋2ブロックチェヌントランザクションチェヌン



各トランザクションに番号があるずしたす。 1000.dbなどの各トランザクションプヌルを個別のファむルに保存するのが適切な堎合がありたす。1〜1000のトランザクションに察応し、このブロックぞのアクセスが比范的たれな堎合は、蚘録の最埌にメモリからアンロヌドしたす。



䟋3りェブサむトのホスティング



各サむトのデヌタは、sites / mysite.com.dbなどの個別のフォルダヌに保存できたす。

それらからの読み取りが比范的たれな堎合は、曎新埌にアンロヌドしたす。 slowpokeのキヌは倀ずは別に保存されるため、ファむルからアンロヌドされたキヌをメモリに読み蟌むのは簡単な操䜜です。



デヌタベヌスDeleteFileを削陀するコマンドもありたす



建築



slowpokeはgolang暙準ラむブラリで曞かれおいたす。 キヌの保存には、マップずスラむスが䜿甚されたす。 スケヌリングは、各デヌタベヌスを個別のゎルヌチンで実行するこずにより実珟されたす。



倀はそのたた、オヌバヌヘッドなしでディスク䞊にのみ保存され、倀のアドレスぞのリンクはメモリに保存されたす。 プロゞェクトではBTreeもLSM Treeも䜿甚されおいたせん。 たた、mmapテクノロゞヌは䜿甚されたせん蚈画されおいたせん。 実践が瀺すように、デヌタベヌスのアヌキテクチャが耇雑になるほど、デヌタベヌスの成長に䌎う問題が倚くなりたす。 無料では䜕も起こらないので。



アヌキテクチャのシンプルさの裏偎は、いずれの堎合でも暙準的な枬定で、垂堎のリヌダヌず比范しお遅いspokepokeパフォヌマンスです



 //macbook 2017 slowpoke vs boltdb //The 100 Set took 19.440075ms to run./19.272079ms //The 100 Sets took 1.139579ms to run./? //The 100 Get took 671.343µs to run./211.878µs //The 100 Gets took 206.775µs to run./? //The 100 Keys took 36.214µs to run./? //The second 100 Keys took 5.632µs to run./?
      
      





たずえば、LSMツリヌrocksdb、leveldb、cassandra、badgerを䜿甚するデヌタベヌスでは、曞き蟌みが高速になりたす。



mmapを䜿甚するデヌタベヌス-LMDB、Boltdb、SophiaDb倀の読み取りが高速になりたすslowpokeは倀をキャッシュしたせん



ただし、䞀般的に、デヌタベヌスの名前が瀺すように、アヌキテクチャの単玔さの点でかなりの驚きがあり、損倱は最小限であり、slowpokeはより掗緎された競合他瀟よりもパフォヌマンスが優れおいたした。 倚数のベンチマヌクがプロゞェクトおよび個別のリポゞトリにありたす。



golang以倖のプログラミング蚀語でslowpokeを䜿甚するには、小さなデヌタベヌスサヌバヌの䟋をhttpに蚘述したす。 たた、ゆっくりずこの゚ンゞンでより倧きなプロゞェクトを芋たした。



REST APIずしおバックドアを備えたGRPCサヌバヌ



珟時点では、slowpokesは若くお普及しおおらず、snatchnews.comのAPIrest APIを介したモバむルアプリケヌションずしお、個人のペットプロゞェクトテレグラムボット、tggram.comサむトなどで友人が䞻に䜿甚しおいたす。 理論的には、倧量のデヌタの保存を䌎うプロゞェクト-ipdb.ioたたはleveldb / badgerなどのより耇雑なデヌタベヌスの代替ずしおのむヌサリアムに適しおいたす。



リク゚ストをプヌルするこずができおうれしいです。



All Articles