Tao Hui http://weibo.com/taohui3
英語版
デザインコンセプト
Lushanは、Memcached Protocolを使用して、複数のライブラリを使用して、軽量のキー価値データベースでした。 Lushanを使用すると、Memcachedのようないくつかのマシンにクラスターを簡単に構築できます。 Lushan 2.0は、複数の共有ライブラリを取り付けることができる軽量アプリケーションフレームワークでもあるため、データにアクセスして1つのプロセスで計算できるようにするため、大規模なデータ量と高性能サービスを簡単に記述することができます。インターネットの推奨、広告、検索のビジネスシナリオに特に適しています。 Lushanは、長年にわたってSina Weiboの推奨事業と広告ビジネスで使用されてきました。
2013年頃、私は「Weiboを逃した」推奨事項を開発していました。さまざまなアルゴリズムとそのオンラインおよびテストバージョンを実験するには、オンラインでいくつかのデータストアを提供する必要があります。これには、いくつかのシステムを展開する必要があります。このアプローチは低すぎます。だから、ある週末、私はLushanを開発しました。
これは事実です。それ以来、LushanはWeiboの推奨事業と広告ビジネスのインフラストラクチャになりました。現在、2つのクラスターがそれぞれ12マシンで操作および維持されており、Tからのオンラインクエリデータを提供し、1日あたり10億を超えるクエリを提供しています。
Lushanの最初のバージョンの開発が終了したとき、私は常にLushanが共有ライブラリを同時に取り付けることを許可する衝動を持っていました。しかし、フレームワークには独自のポジショニングが必要だと信じており、もう1つは簡単に変更された部分を建築の安定した部分から分離する必要があると信じているため、私は長い間決心していません。ただし、Weibo広告を開発する2015年には、ユーザーの関心データ、リレーショナルデータ、およびCTRの推定値の特徴データがHadoopを介して簡単に並べ替え、2つのモジュールを書き込み、ターゲティングとCTRの予測機能を実装できます。そこで、私は元のアイデアをあきらめ、2番目のバージョンを実装し、Lushan関数をさらに強力にしました。実際のアプリケーションでは、Lushanをキー価値データベースとしてのみ使用するか、Weibo広告でも同時にコンピューティングを提供するデータとクラスターのみを提供するLushanクラスターを展開できます。
サンプルライブラリがExamplesディレクトリに提供されており、次の手順に従ってマウントされています。
出力は、キー123456に対応する値です。
各ステップを説明します:
コンピューティングフレームワークとして使用する場合、LushanはHTTP GETの単一ラインの「URL」プロトコルと同様の2つのプロトコルと、バイナリデータの送信もサポートする送信値長を指定するHTTP投稿と同様のプロトコルをサポートします。モジュールディレクトリの2つの例は、それぞれこれら2つのプロトコルを実証するLproxyとLechoの2つの例を示しています。
lproxyの例は、要求されたキーの場合、最初にredisをクエリし、Redisがある場合は直接戻り、Redisがある場合はローカルマウントライブラリを照会します。簡単な場合、この例は、より複雑な要件がある場合は、このコードを変更してください。
以下の手順に従ってください。
テキストファイルx.txtを作成し、次の2行を入力します。最初のタブがキーで、次の値が次のように値です。
168 hello lushan
187 line 2
Lushan_line_makerを使用して、Lushanファイル形式に変換します。
マシンでRedisを起動し、DBNOを1に設定し、レコードを追加し、キーは168、値は「Hello Redis」です
hproxyディレクトリでmakeを実行し、生成されたhmodule.soとhmodule.confをhmod/15/1.0.0ディレクトリに配置し、hmodule.confのホストとポートを変更して、RedisのIPとポートを展開します。
埋め込む:
echo -ne "hmod_open /mnt/lushan/hmod/15/1.0.0/ 15rn" | nc 127.0.0.1 9999
開いた場合、それは正常にオンになります。そうでなければ、libhiredisがld_library_pathにあるかどうかを確認します。
クエリ:
echo -ne "get m15?k=1-168rn" | nc 127.0.0.1 9999
VALUE m15?k=1-168 0 11
hello redis
END
echo -ne "get m15?k=1-187rn" | nc 127.0.0.1 9999
VALUE m15?k=1-187 0 6
line 2
END
次に、予想されるように、Redisが存在する場合、Redisの結果が返されます。そうしないと、LushanデータがQueryedになります。
モジュールを閉じます:
echo -ne "hmod_close 15rn" | nc 127.0.0.1 9999
すべてのモジュールにグローバル変数がない場合は、hmod_openを使用して古いライブラリを直接交換できるため、オンラインサービスに損失がないようにします。
Lechoの例は似ていますが、この例は非常に簡単で、詳細に説明されていません。
Hdictは、Lushanが取り付けたライブラリ形式です。彼はとてもシンプルです。 hdict_xxxxディレクトリ、datとidxには2つの必要なファイルがあります。前者にはデータが含まれており、後者はデータファイルのキーから値への位置オフセットのマッピングです。 意味:
typedef struct {
uint64_t key;
uint64_t pos;
} idx_t;
キーは、ライブラリ番号が含まれていない64ビットの署名の長いスケルトンです。 POSは、値の長さとDATファイルのオフセットで構成されています。
pos = (length << 40) | offset;
IDXファイルは、idx_t.keyの昇順で配置する必要があります。 DATファイルは必要ありません。既に存在するデータファイルにインデックスを作成するか、ファイルを出力すると同時にインデックスを生成することができます。
順序付けられたファイルは、Map-Reduce計算モデルで非常に一般的です。 Hadoopで出力ファイル形式を指定して、hdict形式でライブラリを生成できます。たとえば、次のコマンド:
job.setOutputFormat(LushanFileOutputFormat.class);
統計ステータスデータを取得するには、統計、情報、hmod_infoの3つのコマンドがあります。前者はグローバルデータを出力し、後者は各ライブラリと各モジュールにデータを出力します。
echo -n -e "statsrn" | nc 127.0.0.1 9999
STAT pid 13810
STAT uptime 1435075686
STAT curr_connections 1411
STAT connection_structures 4061
STAT cmd_get 2099151223
STAT get_hits 3950240117
STAT get_misses 2443878402
STAT threads 16
STAT timeouts 117
STAT waiting_requests 0
STAT ialloc_failed 0
END
echo -n -e "inforn" | nc 127.0.0.1 9999
id label state ref num_qry idx_num open_time path
----------------------------------------------------------------
1 interest_CF_trends OPEN 0 139922 18419392 150824-042654 /mnt/lushan/hdb/12/hdict_20150711204737
2 interest_CF_trends OPEN 0 190508 26175141 150824-050246 /mnt/lushan/hdb/12/hdict_20150711204737
echo -ne "hmod_inforn" | nc 127.0.0.1 9999
id label state ref num_qry open_time path
----------------------------------------------------------------
0 OPEN 0 267130787 180419-174502 /mnt/lushan/hmod/0
5 OPEN 0 336829974 180419-174503 /mnt/lushan/hmod/5
lushan.phpを使用して、グラフィカル統計ステータスページを作成できます。
MySQLの経験がある場合は、簡単なクラスターを簡単に作成できます。まず、データをグループ(通常はマシンの番号の倍数)に分割したいと考えています。次に、展開するサービスセットのセット、通常は異なるIDCに分布する2セットのセットを検討します。次に、グループ化ルールに従って、memcachedクライアントを介してデータを照会します。
それは非常に簡単ですが、Lushanはまだデータの送信の詳細を処理するのに役立つ簡単なフレームワークを提供します。
Memcachedプロトコルは比較的簡単ですが、簡単なリクエストのみをサポートしますが、比較的複雑な結果を返すことができます。セットクラスコマンドは複雑な要求をサポートしますが、比較的単純な結果のみをサポートします。 Lushanは、これに2つの変更を加えました。
Get Requestの「キー」は、250バイトの制限を超える可能性があります。 送信時の設定:
memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 0);
このようにして、Libmemcachedを通じて送信するのに問題はありません。結果を返すとき、250バイト以内のキーを返す必要があります。読み取り時に切り捨てられたキーに従って読む限り、切り捨てられたキーは競合しません。
使用は、複数のリクエストの送信をサポートします。通常、簡単なGETリクエストで十分ですが、JSONに似たリクエストを送信する場合は、より複雑なプロトコルが必要です。 LushanはGetSプロトコルを再修正し、SETと同じプロトコルに変更しました。クライアントを使用する場合は、上記の設定を押してキーの合法性を確認し、次の形式でパケットを送信します。
gets key 0 0 value_lenrn
valuern
返品結果にキーを取得するだけです。カプセル化はlutil.hで行われ、hrequest_packに電話するだけです。
統計にはより多くのタイムアウトがあります。または、クライアントからタイムアウト時間までのリクエストを録音します。
特定の数のアップロードの下で送信されていない多くのHDICTファイルがあります。これは通常、送信前に送信スクリプトが中断されることを意味します。