TokyoTyrantベースのCクライアントオープンソースプロジェクトをリリース

11808 ワード

ここでオープンしたのはクライアントの主な机能コードで、オープンソースの目的は一方では多くの人がTCとTTを勉强することを望んで、同时にみんなは本C#ソースコードをダウンロードして引き続き性能を向上させることができて、同时にBUGを探して、必ず本人の精力の能力は有限で、Discuz!NTエンタープライズ版の機能点が多すぎて(時間を割いて多くの文章を書いて紹介します)本当に力が入らなくて、ほほほ:)
では、使いやすいように、ソースコードのプロジェクトファイルについて説明します.ソースコードパッケージには3つのプロジェクトが含まれています.1.Discuz.EntLib.TokyoTyrantコア機能コード(現在のネームスペースは製品名のまま)2.TTSampleは主にテストデータをロードし、SQLSERVERデータベースのクエリー作成機能の速度を比較するために使用されます.      3.TTSampleConsoleがコア機能コードを使用した例(主な機能について説明する)
そのうちDiscuz.EntLib.TokyoTyrantのクラス図は以下の通りである:このクライアントはTcpClient接続プールをサポートUTF-8符号化サポート初期化リンク数、リンク期限切れ時間、最大アイドル時間、最長稼働時間などの設定をサポートする以下に使用方法を紹介する:1.リンクプールの初期化:
 
  
pool = TcpClientIOPool.GetInstance("dnt_online");// ( DNT )
pool.SetServers(new string[] { "10.0.4.66:11211"});
pool.InitConnections = 8;
pool.MinConnections = 8;
pool.MaxConnections = 8;
pool.MaxIdle = 30000;
pool.MaxBusy = 50000;
pool.MaintenanceSleep = 300000;
pool.TcpClientTimeout = 3000;
pool.TcpClientConnectTimeout = 30000;
pool.Initialize();

2.CRUD操作:
レコードを作成します(DISCUZ!NTオンラインテーブルフィールドの例):
 
  
IDictionary columns = new System.Collections.Generic.Dictionary();
columns.Add("olid", i.ToString());
columns.Add("userid", i.ToString());
columns.Add("ip", "10.0.7." + i);
columns.Add("username", " " + i);
columns.Add("nickname", " " + i);
columns.Add("password", "");
columns.Add("groupid", "5");
columns.Add("olimg", "");
columns.Add("adminid", "0");
columns.Add("invisible", "0");
columns.Add("action", "0");
columns.Add("lastactivity", "1");
columns.Add("lastposttime", DateTime.Now.ToString());
columns.Add("lastpostpmtime", DateTime.Now.ToString());
columns.Add("lastsearchtime", DateTime.Now.ToString());
columns.Add("lastupdatetime", DateTime.Now.ToString());
columns.Add("forumid", "0");
columns.Add("forumname", "");
columns.Add("titleid", "0");
columns.Add("title", "");
columns.Add("verifycode", "");
columns.Add("newpms", "0");
columns.Add("newnotices", "0");
TokyoTyrantService.PutColumns(TTPool.GetInstance(), i.ToString(), columns, true);//true tc ,

クエリー操作:
まず、クエリーフィールドolid=1のオンラインユーザー情報などのクエリー(条件)オブジェクトを構築します.このオブジェクトは次のように定義されます.
new Query().NumberEquals("olid", 1)
次にTokyoTyrantServiceのQueryRecordsメソッド(リンクプールのバインドに注意)に挿入します.
var qrecords = TokyoTyrantService.QueryRecords(TTPool.GetInstance(), new Query().NumberEquals("olid", 1));
//現在の結果セットを巡る
foreach (var k in qrecords.Keys)
{
var column = qrecords[k];
...データバインド操作
}
より複雑なクエリーは、次のようになります(forumid=16 and userid<1000をクエリーし、useridフィールドの逆順序で最初の3つのレコードを並べ替えます).
qrecords = TokyoTyrantService.QueryRecords(pool, new Query().NumberGreaterThanOrEqual("forumid", 16).
NumberLessThan("userid", 1000).OrderBy("userid", QueryOrder.NUMDESC).LimitTo(3, 0));
ここでの比較演算子は、次のようにソースコードの列挙タイプを参照できます.
 
  
public enum QueryOperation
{
STREQ = 0, // # : (=)
STRINC = 1, // # : (LIKE ‘% %')
STRBW = 2, // # : (LIKE ‘ %')
STREW = 3, // # : (LIKE ‘% ')
STRAND = 4, // # : (name LIKE ‘% ㈠%' AND name LIKE ‘% ㈡%')
STROR = 5, // # : (name LIKE ‘% ㈠%' OR name LIKE ‘% ㈡%')
STROREQ = 6, // # : ( name = ‘ ㈠' OR name =‘ ㈡')
STRRX = 7, // # :
NUMEQ = 8, // # : (=)
NUMGT = 9, // # : (>)
NUMGE = 10, // # : (>=)
NUMLT = 11, // # : (NUMLE = 12, // # : (<=)
NUMBT = 13, // # : (between 100 and 200)
NUMOREQ = 14, // # : (between 100 and 200)
NEGATE = 1 << 24, // # : negation flag
NOIDX = 1 << 25 // # :
}

クエリーはプライマリ・キーを指定します(この例のolidのように、最も効率的です).
 
  
var qrecords = TokyoTyrantService.GetColumns(pool, new string[]{"1", "2", "3"});
foreach (string key in qrecords.Keys)
{
var column = qrecords[key];
}

更新アクション:
TCTのTCT構造は、レコード内のフィールドを直接更新する機能を提供していないため、関連レコードのすべてのフィールドをすべて取り出してからすべてのフィールドを更新するしかありません(この方法は効率的ではありませんが、MONGODBでは一部のフィールドを更新することができます).クエリーと作成操作の構文を組み合わせて使用するには、次のようにして、該当するレコードを検出し、PutColumnsメソッドを使用してレコードを更新します.
 
  
var qrecords = TokyoTyrantService.QueryRecords(TTPool.GetInstance(), new Query().NumberEquals("olid", 1));
foreach (var k in qrecords.Keys)
{
var column = qrecords[k];
...
TokyoTyrantService.PutColumns(TTPool.GetInstance(), column["olid"], columns, true);//column["olid"] , , ,
}

アクションの削除
この操作には、条件を満たすレコードをクエリーしてから削除(順次削除)する方法と、削除するプライマリ・キーを直接指定して削除(効率が前者より高い)する方法の2つがあります.1つ目(フィールドなしでクエリーし、対応する結果のプライマリ・キーを削除することができます)
 
  
var qrecords = TokyoTyrantService.QueryRecords(TTPool.GetInstance(), new Query().NumberEquals("userid", 1));
foreach (var k in qrecords.Keys)
{
var column = qrecords[k];
...
TokyoTyrantService.Delete(TTPool.GetInstance(), column["olid"]);//column["olid"] ,
}

2つ目(olidが1または2または3または4のキー値レコードを削除し、プライマリ・キーを条件とするレコードのみを削除します):
TokyoTyrantService.DeleteMultiple(pool, new string[] { "1", "2", "3", "4"});
索引の作成
TCでサポートされているいくつかのタイプのフィールドインデックスは、次のとおりです(数値タイプと文字タイプがよく使用されます).
 
  
///
///
///

public enum IndexOption : int
{
LEXICAL = 0, // #
DECIMAL = 1, // #
TOKEN = 2, // # .
QGRAM = 3, // #QGram .
OPT = 9998, // # 9998,
VOID = 9999, // # 9999, .
KEEP = 1 << 24 // # 16777216, .
}

たとえば、オンライン・テーブルでよく使用されるフィールド・インデックスは、次のように設定されています.
 
  
TokyoTyrantService.SetIndex(pool, "olid", IndexOption.DECIMAL);
TokyoTyrantService.SetIndex(pool, "userid", IndexOption.DECIMAL);
TokyoTyrantService.SetIndex(pool, "password", IndexOption.LEXICAL);
TokyoTyrantService.SetIndex(pool, "ip", IndexOption.LEXICAL);
TokyoTyrantService.SetIndex(pool, "forumid", IndexOption.DECIMAL);
TokyoTyrantService.SetIndex(pool, "lastupdatetime", IndexOption.DECIMAL);

3.その他の一般的な操作
 
  
LimitTo(int max, int skip): MYSQL LIMIT , max mssql TOP, skip ( LINQ Skip )
Vanish(TcpClientIOPool pool);
QueryRecordsCount(TcpClientIOPool pool, Query query)//
GetRecordCount(TcpClientIOPool pool)//
GetDatabaseSize(TcpClientIOPool pool);// ( )
IteratorNext(TcpClientIOPool pool)// ,

4.Memcachedと互換性があるため、提供方法のサポート(キー/値ペア)
 
  
Put(TcpClientIOPool pool, string key, string value, bool overwrite)// Put
PutFast(TcpClientIOPool pool, string key, string value)// ( ).
PutMultiple(TcpClientIOPool pool, IDictionary items) //
Delete(TcpClientIOPool pool, string key)//
DeleteMultiple(TcpClientIOPool pool, string[] keys)//
Get(TcpClientIOPool pool, string key)// ( )
GetSize(TcpClientIOPool pool, string key)//
GetColumns(TcpClientIOPool pool, string[] keys)// ( )

5.ソート
public enum QueryOrder
{
STRASC=0,//#ソートタイプ:テキスト型フィールド内のテキスト内容に従って辞書に並べられる順序の昇順を示す
STRDESC=1,//#ソートタイプ:テキスト型フィールド内のテキスト内容に従って辞書に並べられる順序の降順を示す
NUMASC=2,//#ソートタイプ:数値サイズの昇順を表す
NUMDESC=3//#ソートタイプ:数値サイズの降順を示します
}
使用法(降順と上位16件の記録を取るなど):
qrecords = TokyoTyrantService.QueryRecords(pool, new Query().OrderBy("userid", QueryOrder.NUMDESC).LimitTo(16, 0));
注意:ビッグデータセット(100 wレコードなど)のソートをできるだけ避けると、時間がかかります.したがって、OrderByの前にクエリー条件を指定して、クエリー結果セットのサイズを縮小します.
その他の説明:
TTの起動パラメータ(ここではTCTタイプを例にとる):
注意:ネット上にはTC+TTとMONGODB、Redisの速度テストについていくつかありますので、ここではTTの起動パラメータを紹介する必要があると思います.これは最終的なテスト結果にかかわるからです.
どちらもMMAPモードを使用しているため、TC+TTはMMAPを使用するには、次のパラメータを使用します.
xmsiz:TCHDBの拡張MMAPメモリサイズを指定します.デフォルトは67108864、つまり64 Mです.データベースファイルが64 Mを超えると、前の部分だけがメモリにマッピングされるので、書き込み性能が低下します.
bnum:bucket arrayの数を指定します.bnumは、予想される総記録数の0.5~4倍に設定し、keyのハッシュ分布をより均一にし、bucket内での二分検索の時間的複雑さを低減することを推奨する.
たとえば100 wのレコードがあります.ここでは、次のコマンドラインを使用してttserverを起動できます.
ttserver -host 10.0.4.66 -port 11211 -thnum 1024 -dmn -pid/ttserver/ttserver.pid -log/ttserver/ttserver.log -le -ulog/ttserver/-ulim 256m -sid 1 -rts/ttserver/ttserver.rts/ttserver/database.tct#bnum=1000000#rcnum=1000000#xmsiz=1073741824(注:1073741824=1 G)
もちろん、TTServerでは異なるデータベース(TCでは6種類サポート)に対して、対応するパラメータが起動構成(重複)されており、クエリーやデータの挿入の結果に大きな違いがあります.詳細はこのリンクを参照してください.
次に、TC+TT(TCTファイルタイプのみを使用し、他の5つのタイプはこのタイプよりずっと速い)とMONGODBのテスト結果について説明します.
マシンは一般的なデスクトップ:1.5 gメモリ+1.5 gCPU、64ビットcentosマシン、150 gハードディスクです.
mongodb (centos 64bit) :
100000件のレコードを挿入します.所要時間:250377ミリ秒
100000件のレコードに対して、10,000件のレコードを問合せ、時間:8100ミリ秒(時折7500ミリ秒)を費やします(クエリ「_id」プライマリ・キーの速度は6995ミリ秒前後)
100000件のレコードに対して、100000回のレコードをクエリーし、時間:77101ミリ秒
ttcache(centos 64 bit、上の起動パラメータを使用):
10万件のデータを作成するのに589472ミリ秒かかります
10万件のレコードに対して、10,000回のデータをクエリーし、4843ミリ秒かかります.
100000件のレコードに対して、100000回のデータをクエリーし、47903ミリ秒かかります.
注意:実際の生産環境をシミュレートするために、条件の動的変化をクエリーします.
比較すると、MONGODBの挿入速度はTTCACHEより少なくとも2倍速い(MONGODBはWINDOWSでも同様)が、10000回のクエリ速度は約40%-50%遅い.ここでのクエリーと挿入操作は、1回の操作ごとにサーバを接続し、操作が終了すると、長いリンクを開いて一括操作を行うのではなく、現在のリンクをリンクプールに配置します.ここでTTSERVERが使用するクライアントはそれぞれ本明細書のこのツールであり、MONGODBはMongoDBを使用する.Driver.
MSSQLデータベースの操作結果を次に示します.
10,000,000個のデータを一括作成するには、90,20196ミリ秒かかります.
10,000個のデータを一括して問合せ、106040ミリ秒の時間を費やす
10,000件のデータを一括して問合せ、7,738,677ミリ秒かかります.
このようなテストを行うには、WINDOWS(できるだけMONGODBがWINDOWでデータを挿入する速度が速い)や他のオペレーティングシステムを使用しないほうがいいと思います.LINUX(できるだけ64ビット)を使うべきです.もちろんメモリはできるだけ大きくしなければなりません.TC+TTはメモリを節約していますが(必ず日本の国情に合っています.資源が少なくても多くのことをしなければなりません)、クエリーと挿入速度を高めるには、4 g以上のメモリを測定することをお勧めします.
試す.MONGODBはもともとメモリに対する要求が高い(CPUも含む).
mongodbの挿入速度が非常に速く、データベースに新しいファイルを大量に作成して新しいデータを格納できるため(TCTがデータファイルを1つ使用しているわけではない)、より大きなレベルのデータ量の挿入でもパフォーマンスは安定しています.大量のデータストレージの分散ソリューションと見なすことは可能性が高いようです.もちろん、MongoDbとTC/Tを組み合わせて、読み書き分離(TCを読み取りデータベースslavedbとし、同時性とクエリー速度が速い)を実現し、MongoDbを書き込みデータベースmasterdbとして(更新と挿入速度が速い)アーキテクチャを考えています.分散したMongoDbデータファイルをフロントエンドTCのファイルに順次対応させ(C#コードを用いて両者間のデータ同期と論理呼び出しを実現)、両者のそれぞれの利点の結果を融合させる.もちろん今はただの考えで、テキストの内容からますます遠くなっています.ほほほ.
さて、今日の内容はここまで.
ダウンロードリンク:http://tokyotyrantclient.codeplex.com/