基于公共IaaS服务开发应用 — 挑战与对策

By , 2012年5月25日 11:31 上午

基于公共IaaS服务开发应用 — 挑战与对策

这套幻灯片是为5 月25日第四届中国云计算大会的发言准备的文字稿。现场演讲在语言上可能有所不同,但是内容基本上是一致的。请各位同仁多多批评指教。

【讲座主题/自我介绍】

大家好,我叫蒋清野。今天这个讲座的内容,是我对过去几年里在基础构架服务这个领域学习和实践内容的一个总结。虽然这些总结还比较粗浅,我还是愿意通过云计算大会这个平台与大家分享,希望能够得到大家的批评和指正。

(1 分钟)

【IaaS技术】

今天我这个讲座的主题是《基于公共IaaS服务开发应用 — 挑战与对策》。这个主题之所以值得思考,是因为通过基础构架服务所获得的计算资源和传统的计算资源存在一些差别。为了理解这些差别,我们需要简单复习一下IaaS服务所需要的技术。这一张幻灯片是大家都已经非常熟悉的IaaS结构示意图。一般来讲,我们将IaaS相关的技术分成虚拟化技术、虚拟化管理、云服务三个层次。

左上角这张图片是虚拟化技术示意图。通过虚拟化技术,一台计算机可以被虚拟成多台计算机,每台虚拟机在逻辑上拥有独立的处理器、内存、硬盘和网络接口。使用虚拟化 技术能够提高硬件资源的利用率,使得多个应用能够运行在同一台物理机上但是彼此隔离,各自拥有独立的操作系统和其他运行环境。

当我们需要在多台物理机上创建多个虚拟机并且维护多个运行环境时,我们就需要一个工具来帮助我们对物理机和虚拟机进行管理,也就是右上角这个图片里的虚拟化管理。虚拟化管理系统的主要功能包括:(1)通过资源池的方式对物理资源进行重新组织;(2)对所有物理机上的虚拟机进行生命周期管理;(3)基于模板快速部署一系列相同或者是相似的运行环境;(4)监控、报表、预警、会计功能;和(5)高可用性、动态负载均衡、备份与恢复等等。

在虚拟化技术和虚拟化管理的基础上,又逐步出现了终端用户通过浏览器自助式申请、开通、管理计算资源的解决方案,以及通过Web Service API将虚拟机生命周期管理操作暴露给第三方应用的解决方案。终端用户绕过了运维工程师,以自助服务的方式申请、开通、管理计算资源,就是我们最下面这张图所描绘的基础构架服务(IaaS)。

看起来一切都没有问题。

(4 分钟)

【资源超售】

问题在于,虚拟化的计算资源和实际的计算资源是不对等的。目前主流的虚拟化技术都支持超售(over commit)这个功能。 所谓超售,就是提供给用户使用的虚拟资源数量大于实际的资源数量。

以CPU为例,在一台物理机上,操作系统所看到的CPU个数等于物理CPU个数乘以每个CPU的核心数量乘以每个核心的线程数量。假设我的笔记本配置一颗双核CPU,每个CPU核跑两个线程,那么操作系统看见的就是4 颗CPU。在没有超售的情况下,这样一台物理机最多只能够支持4 台虚拟机。在超售的情况下,这样一台物理机所能够提供的虚拟机数量取决于所使用的虚拟化技术。KVM可以将一个物理CPU核虚拟化成10颗虚拟CPU,这样配置一颗双核CPU的物理机最多可以支持到20台虚拟机。

不仅CPU可以超售,内存也是可以超售的。仍然以KVM为例,一台KVM虚拟机相当于宿主机上的一个进程,它所占用的物理内存大小是动态变化的。当虚拟机需要使用内存的时候,宿主机才将所需的内存分配给虚拟机进程。不管在创建虚拟机的时候给虚拟机所指定的内存大小是多少,宿主机上的虚拟机进程所占用的内存仅仅比虚拟机上的操作系统所使用的内存多一点点。当一个虚拟机进程长期处于非活跃状态时,它所占用的内存还会被转移到宿主机的交换分区(SWAP)上。当所有虚拟机所请求的内存总数超过宿主机所配置的内存大小时,宿主机也会用交换分区的空间来充数。可以想象,在内存超售的前提下,如果所有的虚拟机同时运行内存密集型应用的话,就会导致较大的性能问题。

值得庆幸的是,虚拟机的CPU和内存使用率通常不会达到100%,这就给IaaS服务提供商带来了很大的机会。一方面,通过将大量负载较轻的虚拟机集中到少量物理机上,能够大幅度提高资源利用率;另一方面,空闲出来的物理机可以进入休眠状态,从而达到节能的目的。一般来讲,客户的虚拟机对CPU和内存的需求会随着时间发生变化,因此IaaS服务提供商需要有一套监控分析、在线迁移、负载调整的工具才能够在实现超售的同时提供较好的用户体验。可以这么认为,在IaaS服务的时代,超售能力将会是IaaS服务提供商的核心竞争力之一。

对于IaaS的最终用户来说,服务提供商所采取的超售措施是不可见的。在这张幻灯片的右边,我列出了三种可能的虚拟机配置参数,其中CPU参数指的是虚拟机可以使用的CPU核的数量,VCPU参数指的是虚拟机所看到的CPU数量,MEMORY参数指的是虚拟机所看到的内存数量。在没有超售的情况下,虚拟机可以使用一个CPU核,提供一颗虚拟的CPU;在1:2超售的情况下,虚拟机只能够使用0.5个CPU核,提供一颗虚拟的CPU;在1:10超售这种极端情况下,虚拟机只能够使用0.1个CPU核,提供一颗虚拟的CPU。即使不考虑宿主机实际的物理内存是否够用的问题,这三种虚拟机的性能也肯定是不一样的。但是从终端用户的角度来看,这三种虚拟机的配置是一样的。

以前,我们买了台物理机搬回办公室,里面到底有几根内存条几颗CPU拆开机箱一看就知道了。现在我们通过IaaS服务买了台云主机,网页上写着两颗CPU外加2 G内存,但是我们对网页后面到底是什么一无所知。可以这么说,物理机是个白盒子,云主机是个黑盒子。云主机的配置已经退化成一个符号,不再是一个具有确定意义的参数。不但不同IaaS服务提供商之间的产品无法基于配置来进行比较,同一IaaS服务提供商的不同产品之间也很难基于配置来进行比较。这就是基于公共IaaS服务开发应用所面临的挑战。

(7 分钟)

【基准测试】

那么,我们怎么知道某个IaaS服务提供商的云主机是不是能够满足我们的要求呢?要回答这个问题,只能够进行有针对性的基准测试。这张幻灯片对比了三组云主机的UnixBench基准测试结果,其中A 组(红色曲线)是我自己实验室中的云主机,B 组(蓝色曲线)是盛大云正式提供的云主机,C 组(绿色曲线)是阿里云正式提供的云主机。(阿里云的主机配置和其他两组都不一样,勉强按照比较相近的配置归类。)每台主机的测试结果包括两个数据,一个是单线程测试结果,另一个是多线程测试结果(云主机上有几颗虚拟CPU,就有几个并发的测试线程)。从左边这张图中可以看出:(1)不管云主机上有几颗虚拟CPU,单线程测试结果是基本一致的,它反映的是单颗虚拟CPU的处理能力;(2)内存大小对测试结果基本上没有影响;(3)当虚拟CPU的数目增长1 倍时,测试结果增长0.5倍;(4)盛大云主机的测试数据比我自己的云主机的测试数据要低很多。

UnixBench测试结果反映的是一台主机的综合性能,它与被测试主机的CPU、内存、存储、操作系统都有直接的关系。我自己的宿主机配置的是Intel的Xeon E5620处理器,盛大云的宿主机配置的是AMD的Opteron 6172处理器。从cpubenchmark.net提供的数据来看,Opteron 6172的整体处理能力比Xeon 5620高50%以上,单核处理能力也比Xeon E5620高一点点。在内存方面,被测试云主机的内存配置是一致的。在操作系统方面,我自己的云主机和盛大云主机都运行64位Ubuntu 10.04服务器版(阿里云主机运行64位Ubuntu 10.10服务器版)。较大的差异可能在存储方面,我自己的存储基本上处于空闲状态,盛大云的存储可能负载比较高,但是不应该对测试结果产生如此之大的影响。比较合理的推测是盛大云采取了某种超售策略,限制了虚拟CPU的处理能力和虚拟机实际上能够使用的内存数量,从而导致测试结果大幅度降低。

阿里云的CPU和我所使用的CPU单核性能是类似的,UnixBench测试得分也相当接近。值得注意的是经济B 型主机的性能与经济A 型主机相比有明显的下降(图中绿色曲线的下降段),而经济B 型主机和经济A 型主机的配置差别在于经济B 型比经济A 型多了1 GB的内存。也就是说,经济B 型主机的性能应该比经济A 型主机更好才对,但是实际的测试结果正好相反。为了解开这个谜团,我查看了一下经济A 型主机和经济B 型主机的CPU类型,发现经济A 型主机用的是Xeon E5645,是一款比较好的CPU;经济B 型主机用的是Xeon E5620,是一款比较差的CPU。但是新的问题又来了,阿里的经济B 型主机和我实验室中的微型主机采用的是同样的CPU,内存还比我的微型主机多了0.5G,为什么在性能上还比我的微型主机差许多呢?(大家看绿色曲线下降段的点)我想,比较合理的推测还是阿里的经济B 型主机采用了某种超售策略,从而限制了主机的整体处理能力。

表面上配置较高(并且价格也更高)的云主机,由于采用了相对低端的CPU,其性能比表面上配置较低的云主机更低。这就验证了我刚刚说过的一句话:“云主机的配置已经退化成一个符号,不再是一个具有确定意义的参数。不但不同IaaS服务提供商之间的产品无法基于配置来进行比较,同一IaaS服务提供商的不同产品之间也很难基于配置来进行比较。”通过这个例子我们还可以看出,阿里云在基础构架服务产品的设计方面,还是比较业余的。

UnixBench测试程序:http://code.google.com/p/byte-unixbench/

CPU 性能数据:http://www.cpubenchmark.net/

(7 分钟)

【应用测试】

UnixBench测试结果在一定程度上反映了一台主机的整体性能。但是UnixBench毕竟仅仅是一套简单测试的组合,我们所开发或者使用的应用要比UnixBench复杂得多。这里我就以目前比较流行的Hadoop为例,看看它在不同的云主机上的性能如何。在我们下载到的Hadoop软件包中包含了一些作为例子的应用,其中的wordcount应用估计很多人都运行过。这个应用读取输入目录中的文件,计算这些文件中一共有多少个不同的单词以及他们出现的次数。在这个测试中,我使用了三个700MB左右的文件作为测试数据,测试数据一共有2 GB左右。我们在盛大云和阿里云的不同云主机上运行wordcount应用对这些测试数据进行分析,并分别记录完成分析所需要的时间。然后我们将测试数据的大小除以运行时间,代表单位时间内所处理的数据大小(MB/S),用来代表被测配置的测试分数。

我们一共测试了十个不同的配置:分别由一到四台盛大标准主机组成的Hadoop(伪)集群,一台盛大超大主机组成的Hadoop伪集群,分别由一台阿里EA、阿里EB、阿里A 和阿里B 组成的伪集群,以及由阿里A 加上阿里B 组成的集群。从上面这张图表中可以看出,随着计算集群中主机数目的增加,完成测试所需要的时间越来越短,表明计算集群的整体处理能力越来越强。单台盛大超大主机的性能比单台盛大标准主机的性能略好,但是比不上由两台盛大标准主机组成的集群。单台盛大超大主机的测试得分比单台盛大标准主机略高,但是比不上由两台盛大标准主机组成的集群。由四台盛大标准主机组成的集群,其得分是单台盛大超大主机的三倍。阿里A 型主机与阿里B 型主机的性能在同一水平上,虽然阿里B 型主机比阿里A 型主机多配了1 GB的内存,但是对性能提升的帮助非常有限。将阿里A 型主机与阿里B 型主机组成集群后,其性能比单台主机的性能提高一倍。

各位是不是还记得,在上一张幻灯片中我们提到,盛大云超大主机的配置和价格都是标准主机的四倍?换句话说,由四台标准主机组成的集群,在配置和价格上等同于一台超大主机。再换句话说,如果我们使用超大主机的话,性价比是不是有点问题?

(5 分钟)

【性价比】

接下来我们比较一下盛大云和阿里云的主机性价比。这张幻灯片有两张图,上面这张图是基于UnixBench测试结果计算的性价比,下面这张图是基于Hadoop wordcount测试结果计算的性价比。在盛大云系列中,如果以UnixBench测试结果来评价的话,性价比最高的是超微主机,然后依次是微型主机、小型主机、标准主机、大型主机和超大主机。如果以Hadoop wordcount测试结果来评价的话,由一到四台标准主机组成的集群,其性价比是在同一水平线上的;由一台超大主机组成的伪集群性价比最差,勉强达到其他四个配置的1/3。在阿里云系列中,如果以UnixBench测试结果来评价的话,经济A 型主机性价比最高,然后依次是标准A 型、经济B 型和标准B 型主机。如果以Hadoop wordcount测试结果来评价的话,标准A 型主机性价比最高,标准A 型和标准B 型集群次之,标准B 型主机性价比最差。

我们再将盛大云的主机和阿里云的主机进行一下横向对比。在UnixBench测试方面,阿里经济A 型主机性价比最高,然后依次是盛大超微主机、阿里A 型主机、盛大微型主机、阿里经济B 型主机和阿里标准B 型主机。在Hadoop wordcount测试方面,阿里A 型主机的性价比最高,盛大超大主机的性价比最差。盛大标准主机集群比阿里标准B 型以及阿里标准A + B集群的性价比略高。。

值得一提的是,阿里云的主机价格包含了5M带宽的价格,盛大云的主机价格不包含带宽价格。如果我们假设5M带宽的价格为200元的话,那么阿里云主机本身的性价比是全面超过盛大云主机的。

从这张幻灯片还可以看出,性价比不是一个独立存在的概念,它跟用来评估的标准有直接的关系。用不同的标准(或者应用)来评价同一台主机,得到的结果会是不同的。

此外,在IaaS这个特殊的场景中,可以通过修改超售策略来改变某个产品的性能。因此,同一个产品的价格和性能都是可以随时间变化的。如果哪一天盛大云改变了它的定价策略或者是超售策略,这张幻灯片上的数据就不再有效了。(事实上,5 月21日阿里云修改了定价策略,我只好重新计算新的性价比数据。)

(4 分钟)

【横向扩展 vs 纵向扩展】

那么,当我的应用负载出现增长的时候,我们是应该购买更多的标准主机,还是升级到超大主机呢?

横向扩展(Scale Out)和纵向扩展(Scale Up)的目的都是提高一个系统的整体处理能力。如左下角这张图所示,横向扩展是把计算负载分布到多个节点上,纵向扩展则是给一个节点增加更多的计算资源。在前面两张幻灯片中我们已经看到,由多台标准主机组成的计算集群在性能和性价比两个方面都超过超大主机。除此之外,横向扩展还这能够给我们带来更多的好处,包括:(1)让系统构架变得清晰,使故障诊断变得容易;(2)避免了单点失效,提高了系统的健壮性;和(3)可以通过动静分离和读写分离等手段进一步提高系统的性能。因此,当应用需要更强处理能力的时候,我们应该优先考虑横向扩展而不是纵向扩展。

右上角是一个典型的Web 应用横向扩展示意图。各位只要是做过网站的,一定非常熟悉这个构架,这里我就不详细解释了。

(2 分钟)

【云硬盘 vs 云存储】

经常有人问:当我需要存储空间的时候,应该选择云硬盘呢还是选择云存储?

在这里我们先澄清一下概念。云硬盘是一种虚拟的块设备,可以像U 盘一样挂载到云主机上。一块云硬盘在同一时刻只能挂载到一台主机上。如果有多台主机需要同时访问同一块云硬盘,则需要通过NFS等手段进行共享。终端用户需要经过云主机才能够访问到云硬盘上的数据。Amazon所提供的EBS服务,属于我们所说的云硬盘。云存储则是一种Key/Value数据存储服务,用户通过API进行数据存取操作,也可以通过S3FS等手段将云存储作为虚拟硬盘同时挂载在多台云主机上。终端用户访问云存储的数据,不需要经过云主机。Amazon所提供的S3服务,属于我们所说的云存储。

从云主机的角度来看,理论上云硬盘的终极性能要高于云存储的终极性能。这是因为在云存储上存取数据的时候还有一些额外开销,这个额外开销在同时存取大量小文件时会比较突出。从终端用户的角度来看,由于访问云硬盘的数据需要经过云主机,云主机的负载就成了影响用户体验的一个不确定因素。终端用户访问云存储的数据不需要经过云主机,用户体验不会受到云主机的影响。此外,单块云硬盘的容量是存在某些物理条件限制的,而云存储几乎可以 不受限制地向上扩容。

最右边这个方案C,是一些厂商正在进行的云存储+CDN的尝试。也就是说,使用云存储存取数据的用户,未来可以自动地享受到CDN的服务。当用户访问你的应用时,静态文件会自动地从离用户最近的地方分发给用户。考虑到云存储技术未来还有很大的发展空间,我个人的观点是,除非你运行的是需要高速访问磁盘的科学计算型应用,还是尽可能使用云存储来存取数据。

云存储与CDN的融合,是未来基础构架服务领域的一个重要发展方向。建议各位做基础构架服务的同仁多加关注。

(4 分钟)

【Web应用桌面化】

在基础构架服务这个领域,还有哪些方向是值得关注的呢?

上个月在美国隆重召开了一个OpenStack大会。大会结束之后,在新浪微博上看到这样一段话,让我思考了很长时间。这位微博用户说道:“来OpenStack大会的最大收获就是:做云计算的人实在太多了…大家干的都差不多,觉得再这么下去很没前途,尤其是开源云软件让大家都没了特色,全是一个模子刻出来的,拼市场拼销售的话会死掉很多小公司,要仔细研究今后的道路,如何才能突出重围?”

要在激烈的竞争当中脱颖而出,就需要寻找自己与别人的差异点。我之前写过一篇文章,题目是《开源IaaS软件的比较》,其中提到“开放源代码的IaaS解决方案要进入生产环境,还有很长的路要走”这样的观点。也就是说,创业型的IaaS服务提供商还有很多可以进行创新的领域。举个例子说,如果别人的IaaS服务全是一个模子刻出来的,那么我们是不是可以在用户界面上有点创新?

自从互联网问世以来,客户端技术一直都在不断的发展。从纯文本到多媒体内容,从静态页面到富互联网应用,人们对用户体验的期望值越来越高。但是在基础构架服务这个领域,研发人员似乎把全部的精力都放在计算、网络、存储、构架等方面,对用户体验的要求还停留在20年前的水平。这不由得让我想起几年前我还在Sun 公司工作时候的情景。当用户抱怨我们的Solaris操作系统不够好用的时候,我们的工程师总是说“我觉得挺好用的啊,你为什么觉得不好用呢?”或者是“你想要的功能像我这样做就可以了啊,你为什么一定要那样做呢?”。

各位现在看到的这张图片,是我们团队正在开发的一款IaaS产品的截图。这是一个Web应用,但是借用了桌面应用的表现形式和交互方式,我们把它叫做“Web应用桌面化”。在过去几年当中,我们观察到一个很有意思的现象。一方面,传统的桌面应用往Web应用迁移;另一方面,Web 应用在表现形式和交互方式上模仿传统的桌面应用。对于一些重量级的应用而言,Web应用目前似乎仅仅是桌面应用的补充,但是它们在未来的五到十年里可能会全面取代桌面应用。如果各位花时间看一看腾讯的Web QQ、微软的Office 365以及Adobo在线版本的PhotoShop,就会深信这不仅仅是一个试验性的方向。

我们正在开发IaaS产品就是这样一个应用。它用桌面图标代替了文字链接和图片链接,用窗口的打开和关闭代替了页面跳转,用右键菜单提供了主机和网络的管理功能。更重要的是这个应用提供了类似多线程的体验,你可以同时打开多个窗口进行操作,随时在多个窗口之间自由切换。不管你做什么操作,你永远都停留在同一个页面里面,没有页面跳转,也不用等待页面跳转。

各位是不是觉得这样一个IaaS产品很有意思?在这里我们花一点时间做一个简单的演示。

(6 分钟)

下载演示视频

【ezCloud演示】

这是我们的登录页面,看起来有点像Linux操作系统的登录界面。除了传统的用户自助注册功能之外,我们也允许用户直接使用他的新浪微博登录使用我们提供的服务。

登录成功后,进入我们的功能页面。我们先点一下这个图标将页面全屏显示,这样它看起来就更像一个桌面应用了。

在桌面上我们用一系列图标来表示用户可以进行的操作。譬如说用户要购买新的云主机,他就可以点击这个“购买主机”图标。这时候页面上就会弹出购买主机的窗口,在这里用户可以选择数据中心、硬件配置、操作系统,给云主机命名以及设定访问密码,还可以一次性创建多台相同配置的云主机。用户点击“购买”按钮之后,还会跳出一个窗口要求用户确认订单信息。用户确认订单之后,后台立即启动创建云主机的进程,并通过进度条来告知用户当前的进度。大概三十秒之后,用户的云主机就创建好了。

用户的云主机创建完毕后,系统自动打开主机管理窗口。大家可以看到,我们是通过分组的形式来组织和管理云主机的。新创建的云主机会自动出现在“所有主机”这个分组里。我们点击某个分组的图标,就会列出这个分组里面的所有主机。我们点击某台主机的图标,然后点击鼠标右键,就会弹出一个菜单,列出用户可以进行的操作。譬如说,用户可以登录进入主机控制台,可以监控主机的CPU、内存和网络活动信息,可以修改主机的名称和分组,还可以重启、重建和删除主机。

同样,我们也可以通过同样的方式购买网络和管理网络。在管理网络窗口里,我们可以将购买到的网络绑定到某台云主机上,也可以随时解除网络和云主机的绑定,也可以删除我们购买到的网络资源。网络的绑定和解除绑定操作都是实时生效的,大概10秒钟左右用户界面上的图标也会发生改变,以反映网络状态的改变。

通过这几个例子大家可以看到,用户的操作都是在弹出窗口里完成,没有发生页面跳转。这种新的表现形式和交互方式,有效地提高了用户的使用体验。由于时间关系,我就不一一演示这个系统的其他功能了。如果有听众对这个系统的细节感兴趣的话,可以在会后跟我联系。

(5 分钟)

【结束致谢】

Web应用桌面化仅仅是创新的开始。在基础构架服务逐渐成为趋势的大前提下,如何有效定义云主机的配置参数,如何在超售的同时保证云主机的性能,如何帮助客户快速创建高性能的计算集群,如何帮助客户实现自动化的横向扩展,怎么样帮助客户从原来的硬盘存储方案平滑过度到云存储方案,怎样实现云存储与CDN的无缝融合,都是我们团队正在深入研究的内容。

今天我的讲座到这里就结束了。各位如果需要更多的资料,包括今天这个讲座的幻灯片和文本,都可以从我的博客获得。谢谢大家。

(1 分钟,共计45分钟)

【后记】

由于我的讲座安排在上午的最后一个时段,估计在场的听众都等着去吃饭。分配给我的时间是40分钟,但是要讲完如上内容我估计需要46分钟,超时6 分钟。因此,在现场我会砍掉【IaaS技术】、【资源超售】和【Web应用桌面化】的部分已经广为人知的内容,【ezCloud演示】部分必须控制在5 分钟以内。最终要保证这个讲座绝对不超时,最好能够提前两分钟结束。

 

7 Responses to “基于公共IaaS服务开发应用 — 挑战与对策”

  1. Ken说道:

    让牛逼的技术更加贴近客户才有意义,用户体验是互联网应用的核心

  2. Martin Zhang说道:

    wanna be the friend and business partner if it is possible.

  3. beyes说道:

    最怕就是超售,一般会买 XEN 的 Linux,但是这个价格又高些;买了米国洛杉矶的 OpenVZ ,但是这个架构又容易超售。只能在国内找个所谓的“云分发”来缓解服务器和线路缓慢问题。我没有确切知道云是什么,在模糊的理解中,就是多个服务器在一个机制下,互相连接,互相合作。小的如同硬盘 raid 也可以理解为几多小云吧。

  4. xying222说道:

    请问为什么你会把cloudstack放在虚拟化管理那类,而不是IaaS?

  5. qyjohn说道:

    CloudStack + CloudBridge才是一个完整的IaaS。

  6. zheng说道:

    请问“一颗双核CPU,每个CPU核跑两个线程的电脑”,能通过KVM虚拟出40颗CPU还是20颗?
    谢谢!

  7. […] 回答:看看蒋清野的这篇博客,讲国内IaaS的现状和挑战,对阿里云和盛大云的评价讲也非常客观。http://www.qyjohn.net/?p=1948 […]

Leave a Reply

Panorama Theme by Themocracy