🌡️

HottyDB(次世代型RDBMS)の地味だけどスゴい機能を紹介します!!

2022/10/12に公開約3,500字

HottyDB[1]は、検索エンジンとレコメンドエンジンの機能を搭載したRDBMS(リレーショナルデータベース)です。

https://www.hottydb.com/

本記事では、HottyDBの地味だけどスゴい機能として「メトリクステーブル」という機能を紹介したいと思います。

メトリクステーブルとは?

メトリクステーブルとは、例えば記事のアクセス数や商品の閲覧数などをカウントする際に役立つ機能です。

通常のテーブルでアクセス数などをカウントする場合、書き込み処理になるため排他ロックを取得する必要があります。排他ロックはその名の通り、その他のトランザクションの書き込みや読み込みを全て禁止します。そのためアクセス数のように、頻繁に更新が発生する処理があると全体の処理性能が大きく悪化してしまいます。

メトリクステーブルは、READ用テーブルとWRITE用テーブルを2つずつ用意し、多少の値の反映遅延を許容することで、ロックフリーな読み込みと書き込みを実現した専用テーブルです。

メトリクステーブルの使い方

まずさいしょにメトリクステーブルの使い方について説明します。そのあと、その仕組みについて解説したいと思います。

メトリクステーブルの作成

例として、page_viewという名前のメトリクステーブルを作成します。
page_viewPRIMARY KEYidというフィールドを持ち、メトリクスフィールドとしてnumというフィールドを持ちます。

CREATE METRICS TABLEの例文

CREATE METRICS TABLE page_view 
(id INT PRIMARY KEY, num INT) 
FLUSH_FREQ = 25

CREATE METRICS TABLEの構文はCREATE TABLEの構文と似ていますが、 以下の違いがあります。

  • PRIMARY KEY
    • メトリクステーブルは必ずPrimary Keyを必ず持つ必要があります
    • 裏側のシステムでは、Primary Keyで指定したフィールドでGroup byし、それ以外のフィールド(メトリクスフィールド)をSUM集計しています
  • FLUSH_FREQ
    • 更新結果をREAD用テーブルに反映するまでの更新回数を指定します
    • オプションのコマンドで、指定しなければデフォルト値の100回となります

メトリクステーブルへの加算

先ほど作成したpage_viewテーブルのid=4のレコードに、num += 1の加算をしたいと思います。

ADD METRICSの例文

ADD METRICS INTO page_view (id, num) VALUES (4, 1)

このように、ADD METRICS命令は INSERT命令とよく似た構文で記述することが可能です。

ADD METRICSの例文2

下記のように、マイナスの値を加算することで、減算も可能です。

ADD METRICS INTO page_view (id, num) VALUES (4, -3)

ADD METRICS命令をFLUSH_FREQで指定した回数実行すると、自動的に集計処理が走り、読み込みテーブルへの反映が行われます。
読み込みテーブルも書き込みテーブルも裏側では2つずつ用意してあるので、利用者はこのスイッチ処理の間も遅延なく書き込みと読み込みを行うことができます。

メトリクステーブルの参照

メトリクステーブルは通常のテーブルと同じように扱うことが可能で、下記のようなSELECT文で参照可能です。

SELECT id, num FROM page_view

また、AI検索システムの作り方の記事で解説した機械学習ランキングの特徴量としても利用可能です。
メトリクステーブルを機械学習ランキングの特徴量として利用したサンプルコードがありますので、そちらをぜひ参照してみてください。

機械学習ランキング+メトリクステーブルのサンプルコード(後半部分のコード)

メトリクステーブルの仕組みを解説

メトリクステーブルがロックフリーとなる仕組みを解説したいと思います。

m1というメトリクステーブルを作成した場合、HottyDBの裏側では、下記のように2つのREADテーブルと2つのWRITEテーブルを作成します。

メトリクステーブル説明

2つのうち、どちらか一方がアクティブなテーブルとなりますが、この図の場合 READもWRITEもどちらも A がActiveなテーブルとなります。

通常期

上図のように、SELECT文ではアクティブなREADテーブルを参照します。
READテーブルには更新処理が発生しないので排他ロックがかからずロックフリーとなります。

ADD METRICS命令ではWRITEテーブルを更新しますが、WRITEテーブルには参照処理が発生しないので、書き込み処理のみで競合が発生します。
また、ADD METRICS命令は追記(INSERT)のみの更新となるため、ほとんどがメモリ上の操作となりほぼロックがかかりません。
さらに、通常のテーブルであればトランザクションログ書き込みがDISK書き込みになりますが、メトリクステーブルではトランザクションログ書き込みもしていませんので、ロックの競合を最小限に抑えることができています。
※その代わり、ロールバックなどはできません。

スイッチ処理

ADD METRICS命令をFLUSH_FREQで指定した回数実行すると、スイッチ処理が走ります。
図(READもWRITEもAがアクティブ)の状態からスイッチ処理を行う過程を説明します。

1. WRITEアクティブの切替

まずWRITEのアクティブを B に切り替えます。
これで以降のADD METRICS命令は、B に追記していきます。

メトリクステーブル_スイッチ1

2. 集計処理

次に m1.READ.Am1.WRITE.A を GROUP BY集計で集計した結果を m1.READ.B に書き出します。

メトリクステーブル_スイッチ2

3. READアクティブの切替

最後に READのアクティブを B に切り替えます。

メトリクステーブル_スイッチ3

以上のようにスイッチ処理を実施することで、ロックをすることなくテーブルの更新を実行することができるのです!

さいごに

以上で本記事は終わりです。

是非皆様もHottyDBを活用していただき、忌憚ないフィードバックをいただけると幸いです。
(フィードバックはこちらまで)

脚注
  1. HottyDBに関しては前回の記事で詳しく説明していますので、こちらも参照してください。 ↩︎

Discussion

ログインするとコメントできます