- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Discuz!NT千万级数据量上的两驾马车 TokyoCabinet,MongoDB由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
特别是像主题表(topic),用户表(user)等,因为对于一个流量和发帖量都很大的论坛而言,在运行几年之后,这两个表的数据量可能会破千万(注:因为帖子表采用分表机制,所以这里暂未涉及,但出于性能考虑,也提供了本文中类似的解决方案)。当时考虑的架构设计中有两种思路来解决这种问题: 一种是采用类似MYSPACE的方式,即按一定记录KEY值(比如用户表的UID)来对大数据表中的记录进行分割,比如前200万用户(即:UID<200w)放入一个表,200-400万的用户放入另一个表,以此类推。当然可以把几个表都放到一个数据库中,也可以放到别的MSSQL数据库上或实例上。但这种方案有一些问题,例如当用户表需要被联表(如LEFT JION)查询时使用,比如我们的帖子表进行分页查询时就需要左联user表,这时如采用分表或分布式布署就可能面临这样的问题,不仅业务逻辑要变化,就连存储过程中也要产生不小的变化,这里还不考虑效率上的问题。当然有人建议可以使用数据冗余的方式,比如在帖子表中冗余用户信息相应字段,但这种方案同样要大幅度的修改即有代码,同时如果用户信息发生变化时,不仅要更新用户表,还要更新帖子表中的相应冗余字段,如果这两者不同步,就会造成数据显示异常,当然在数据库层面增加存储成本也是不得不付出的。 第二种就是使用能处理大数据量表格的第三方工具,比如本文所说的TokyoTyrant,Mongodb等,这类NOSQL软件从一问世就是面向海量数据存储访问的,而且这类软件往往都是开源的,另外通过与打算布署企业版的用户接触,发现虽然他们的服务器配置很高,但数量即不多,所以就要考虑如何最大限度的复用已有的机器资源,而这类NOSQL软件往往都是‘性价比’很高的,即用不多的资源(内存,CPU等)就能达到意想不到的效果。当然我目前对其还是很谨慎的使用,即不会马上把它当做主力数据存储工具,而是辅助MSSQL数据库工具,所以大家在看完本文后会发现,这两个工具在企业版中的角色顶多就是一个高级的MEMCACEHD。不过我的想法很简单,就是任何工具和技术,如果不是很了解它或者它很新,那么必定要有一个“考核期”,如果在‘任间’内它通过考核,才委以重任,如未通过考核,也不会让系统平台承担过多的技术层面上的‘风险’.
综上所述,最终我把方向放到了TokyoTyrant,Mongodb上,之所以选择了这两个工具,主要基于下面因素: 1.海量数据的解决方案应该可以跑在LINUX和WINDOW平台上。当然有人会说Mongodb完全可以跑这两个平台,那还为什么要引入TokyoTyrant呢?其实这里有一些产品的特殊情况要考虑,比如我们的用户中绝大多数对于数据的读写比在 4:1,即5条SQL访问中有4条是SELECT操作,1条是CUD操作,这就造成了读写比例的失衡。虽然Mongodb在读写性能上非常优异和稳定,但在并发读上相对于TokyoTyrant+cabinet还是有一些差距(注:更多内容参见该链接,然后这只限于在我们产品中压力测试环境下的结果,不具备普遍性,所以希望大家具体问题具体分析) 。
2.考虑到有些用户公司是有相应技术储备的,两种方案也便于用户公司进行的技术选型(当然因为采用接口方式,用户完全可以引入其它第三方的NOSQL工具来实现).
好了,说了这么多,开始今天的正文吧。 前面说过,该方案使用了接口方式,这里就先看一下相应的接口声明: 。
可以看到,目前在企业版中,对主题表(dnt_topics),用户表(dnt_users),在线表(dnt_online)以及帖子表(dnt_posts)进行了NOSQL数据支持,所以定义了如下的几个接口(图中): 。
因为目前只是把这类NOSQL工具当作高级的‘缓存’来用,所以接口命名上都带着‘Cache’的字样。 然后我使用了一个叫做DBCacheService的类,提供获取这几个接口实例的方法,比如ICacheTopics的实例代码如下: 。
从上面代码可以看出,使用反射方式获取相应DLL文件(分别是Discuz.EntLib.TokyoTyrant.dll和Discuz.EntLib.MongoDB.dll)中的 类信息并初始化该实例。当然,这里还定义了一个配置文件,也就是EntLibConfigs.GetConfig()这个方法所获取的配置文件信息, 相应 配置文件内容包括: 。
上面是配置文件中‘可复用信息’的基类,下面是具体的配置类实例声明: 。
通过该类,就可以用如下配置文件内容初始化相应的实例了: 。
当然,因为使用的开源的客户源工具在配置上有一定的的差异性(比如命名上等),所以这里有些参数可以对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的写法(也算是扩展和尝试吧),如下面的写法(更多具体示例还是参见其官方源码包中的相应内容): 。
不过在使用上述代码进行1500万主题分页时,发现LR的测试周期延长(前者(document方式)从2:10秒延长到后者(linq)2:30秒)和吞吐量降低。 所以这里还是最终延用了samus的document访问方式,参照上面的LINQ写法,下面是document写法,形如: 。
如果在你的项目中非要使用LINQ方式的话,那在这里再要介绍的一个samus的属性绑定功能,这个功能对于那些数据库字段与代码中的属性存在 “大小写”差异的情况下,非常有用,即对相应实体类进行‘别名’的绑定,比如对于主题表(需引入MongoDB.Attributes名空间): 。
上面的MongoAlias属性就是属性别名,它就是MONGODB中所存储的数据字段名称。 介绍到这里,再回到正文。 因为这两个工具都是在数据库层面进行缓存的,所以它对于原有的DISCUZ!NT中的缓存系统而言,与数据库帖的更近,所以对原有的业务逻辑改造, 就停留在了数据访问层"DISCUZ.DATA.dll"中了,其实到这里,就看出了当初为什么要分层,以及分层带来的好处了。 比如在Discuz.Data.Topics这个类中添加了这两个静态变量: 。
前者用户判断是否启用主题缓存,后者则获取相应的缓存服务实例(前面配置文件中已做相应说明)。 这样,在已有的数据访问代码中加入相应的缓存逻辑,比如获取主题信息: 。
当然,因为使用了缓存方式,所以就牵扯到缓存中的数据与数据库中数据的一致性问题,所以对于主题的CUD操作,也要对应有相应的对缓存的操作,这基本上就是一个工作量的问题了。因为无论是TTCACHED,还是MONGODB,都支持更新操作。 比如同样是更新主题附件类型的操作,下面是TTCACHED的写法: 。
下面是MongoDB的写法 。
通过对比可以看出,MONGODB可以对某一字段进行操作,而TTCACEHD则只能通过查询先获取整条记录,然后修改某一‘字段’,之后再整条提交更新,所以单从这一角度讲,MONGDOB要比TTCACHED更新性能要高许多(之后的测试结果也说明了这一点)。 正如之前所说的那样,如用户对于这两个接口实现方案均不满意,那么他可以使用其它类型的NOSQL数据库,只要实现了相应的接口: public interface ICacheTopics public interface ICacheUsers public interface ICacheOnlineUser public interface ICachePosts 并在配置文件中进行相应的配置就可以了,当然本文中代码因为时间问题还是有待考量的,但主要的架构设计思想基本被确定下来了。 当然对于原有的数据库中的记录,如果要使用本方案,我提供了转换工具,用于把数据转到TTCACHED或MONGODB中的任一服务端上。如下: TTCACEHD: MongoDB(目前比TTACEHD多了帖子分表转换功能): 最后在压力测试过程中,还出现了一些小问题,好在对着官方文档,逐步优化解决了,这里要特别说一下MONGDOB,其文件的详细程度要好于TTCACHED,基本上主要的功能都有详细的介绍说明页面,呵呵。当然TTCACHED的诞生时间要比MONGODB早,所以在生产环境下的成功案例也相对多一些。 下面列了一下使用过程中的小问题,仅作记录: TokyoTyrant的使用问题:尽量不要在查询的列表中使用排序操作,因为它的排序效率还不如数据库高。尽量使用索引进行查询 键值操作。2000w记录以下查询效率很高,但更高的数据量上目前没做过压力测试(包括CRUD操作) Mongodb:尽量使用_ID做为查询键值操作,包括排序等,对索引进行优化(单列或多列进行索引).
最后此篇关于Discuz!NT千万级数据量上的两驾马车 TokyoCabinet,MongoDB的文章就讲到这里了,如果你想了解更多关于Discuz!NT千万级数据量上的两驾马车 TokyoCabinet,MongoDB的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我的一个 friend 在一次求职面试中被要求编写一个程序来测量可用 RAM 的数量。预期的答案是以二进制搜索方式使用 malloc():分配越来越大的内存部分,直到收到失败消息,减少部分大小,然后对
我正在通过任务管理器检查 Chrome 中特定选项卡的内存消耗情况。它显示了我使用的 RAM 量相当大: 但是,当我在开发人员工具中拍摄堆快照时,其显示的大小要小几倍: 怎么会这样呢? 最佳答案 并非
是否有一种可移植的方式,可以在各种支持的操作系统上同时在 .Net 和 Mono 上运行,让程序知道它运行的机器上有多少 RAM(即物理内存而不是虚拟内存)可用? 上下文是一个程序,其内存要求是“请尽
有谁知道是否有办法查看 android studio 项目中的所有 View 、LinearLayout、TextView 等? 我正在使用 android 设备监视器中的层次结构查看器使用 xml
很简单,我想从 Python 脚本中运行外部命令/程序,完成后我还想知道它消耗了多少 CPU 时间。 困难模式:并行运行多个命令不会导致 CPU 消耗结果不准确。 最佳答案 在 UNIX 上: (a)
我需要在给定数组索引和范围的情况下,在返回新索引的数组中向前循环 X 量并向后循环 X 量。 如果循环向前到达数组的末尾,它将在数组的开头继续。如果循环在向后时到达开头,它会在数组末尾继续。 例如,数
Android 应用程序中是否有类似最大 Activity 的内容?我想知道,因为我正在考虑创建具有铃声功能的声音应用程序。它将有大约 40 个 Activity 。但只有 1 个会持续运行。那太多了
有什么方法可以限制这种演示文稿的 curl 量吗?我知道系统会根据我们以 taht 方式模态呈现的 viewcontroller View 内的内容自动 curl 。 但 thta 在我的 iPad
我正在编写一个 Java 应用程序,它需要检查系统中可用的最大 RAM 量(不是 VM 可用的 RAM)。有没有可移植的方式来做到这一点? 非常感谢:-) 最佳答案 JMX 您可以访问 java.la
我发现它使用了 600 MB 的 RAM,甚至超过了 Visual Studio(当它达到 400 MB 的 RAM 时我将其关闭)。 最佳答案 dart 编辑器基于 Eclipse,而 Eclips
这个问题已经有答案了: Java get available memory (10 个回答) 已关闭 7 年前。 假设我有一个专门运行一个程序的 JVM,我如何获得分配给 JVM 的 RAM 量? 假
我刚刚使用 Eclipse 编写了一个程序,该程序需要很长时间才能执行。它花费的时间甚至更长,因为它只将我的 CPU 加载到 25%(我假设这是因为我使用的是四核,而程序只使用一个核心)。有没有办法让
我编写了一个 2x2x2 魔方求解器,它使用广度优先搜索算法求解用户输入的立方体位置。该程序确实解决了立方体。然而,当我进入一个很难解决的问题时,我会在搜索的深处发现这个问题,我用完了堆空间。我的电脑
我正在尝试同步运行多个 fio 线程,但随着线程数量的增加,我的计算机内存不足。似乎每个 fio 线程占用大约 200MB 的 RAM。话虽这么说,有没有办法让每个线程都有一个固定的最大内存使用量?设
我使用“fitctree”函数(链接:https://de.mathworks.com/help/stats/classificationtree-class.html)在 Matlab 中开发了一个
我有一个 .NET 进程,由于我不会深入探讨的原因,它消耗了大量 RAM。我想要做的是对该进程可以使用的 RAM 量实现上限。有办法做到这一点吗? 我找到的最接近的是 Process.GetCurre
您可能已经看到许多“系统信息”应用程序,它们显示诸如剩余电池生命周期之类的信息,甚至显示内存等系统信息。 以类似的方式,是否有任何方法可以从我的应用中检索当前可用 RAM 量,以便我可以更好地决定何时
我从来都不是 MFC 的忠实粉丝,但这并不是重点。我读到微软将在 2010 年发布新版本的 MFC,这让我感到很奇怪 - 我以为 MFC 已经死了(不是恶意,我真的这样做了)。 MFC 是否用于新开发
我在一台安装了 8 GB 内存的机器上工作,我试图以编程方式确定机器中安装了多少内存。我已经尝试使用 sysctlbyname() 来获取安装的内存量,但它似乎仅限于返回带符号的 32 位整数。 ui
基本上,我想要一个由大小相同的 div(例如 100x100)和类似 200x100 的变体构建的页面。它们都 float :向左调整以相应地调整窗口大小。问题是,我不知道如何让它们在那种情况下居中,
我是一名优秀的程序员,十分优秀!