Discuz!NT千万级数据量上的两驾马车 TokyoCabinet,MongoDB

2019-02-18 00:52:00王振洲

当然,因为使用的开源的客户源工具在配置上有一定的的差异性(比如命名上等),所以这里有些参数可以对TTCACHE有效,却对MONGODB无效, 不过这并不影响对这两种工具的使用。
 
      这里要说明的是,对于TokyoTrant而言,这里使用的是我开发的这款客户端软件:

      http://www.cnblogs.com/daizhj/archive/2010/06/08/tokyotyrantclient.html


      Mongodb使用的是:http://github.com/samus/mongodb-csharp。
    
      这里还有个小插曲,之前园子里有朋友介绍了这个客户端NoRM ,不过在我写了一个LINQ示例并进行压力测试后,发现速度不快,比samus的那个客户端慢了不少,在苦找原因无果的情况下,最终选择了samus,不过在samus中目前也支持LINQ的写法(也算是扩展和尝试吧),如下面的写法(更多具体示例还是参见其官方源码包中的相应内容): 


Mongo db = new Mongo("Servers=10.0.4.5:27017;ConnectTimeout=30000;ConnectionLifetime=300000;MinimumPoolSize=64;MaximumPoolSize=256;Pooled=true");
db.Connect();
var topicColl = db.GetDatabase("dnt_mongodb").GetCollection<Discuz.EntLib.MongoDB.Entity.TopicInfo>("topics");
var topicInfoList = topicColl.Linq().Where(t => t.Fid == 2 && t.Displayorder == 0).Skip(skip).OrderByDescending(t=>t.Lastpostid).Take(16).ToList();
Discuz.Common.Generic.List<TopicInfo> topicList = new List<TopicInfo>();
foreach (var topic in topicInfoList)
{
topicList.Add(LoadTopicInfo(topic));
}
db.Disconnect();
return topicList;

不过在使用上述代码进行1500万主题分页时,发现LR的测试周期延长(前者(document方式)从2:10秒延长到后者(linq)2:30秒)和吞吐量降低。
所以这里还是最终延用了samus的document访问方式,参照上面的LINQ写法,下面是document写法,形如:


public Discuz.Common.Generic.List<TopicInfo> GetTopicList(int fid, int pageSize, int pageIndex, int startNumber)
{
int skip = 0;
if (pageIndex <= 1)
pageSize = pageSize - startNumber;
else
skip = (pageIndex - 1) * pageSize - startNumber;
Discuz.Common.Generic.List<TopicInfo> topicInfoList = new Common.Generic.List<TopicInfo>();
System.Collections.Generic.List<Document> docList = MongoDbHelper.Find(mongoDB, "topics",
new Document().Add("fid", fid).Add("displayorder", 0), "lastpostid", IndexOrder.Descending, pageSize, skip);
return docList;
}

如果在你的项目中非要使用LINQ方式的话,那在这里再要介绍的一个samus的属性绑定功能,这个功能对于那些数据库字段与代码中的属性存在 “大小写”差异的情况下,非常有用,即对相应实体类进行‘别名’的绑定,比如对于主题表(需引入MongoDB.Attributes名空间):