Elasticsearch学习笔记——集群设计
问题:我的es需要应该如何设计集群?
程序员:老板,我们需要购置一些服务器,用于es集群。
老板:好的。那需要什么配置?需要几台呢?
程序员:……嗯,要不,先搞两台试试?
老板:我考虑把你换掉试试。
数据量和数据增长情况
要设计一个合理的es集群,首先你应该对当前系统的数据量以及数据增长情况有一个了解。一般情况下,要通过es进行索引的数据,事实上已经存在于某个数据库中了(无论是关系性还是非关系性),那么,我们只需要对当前数据库中已有数量的大小进行一个计算,就可以得到系统的数据量。通过若干个时间点的系统数据量大小的比较,就可以得到数据量的一个增长情况。
以MySQL为例,我们可以做如下分析:
一个MySQL服务器上,通常有若干个库,库里有若干个表,表里有若干行数据,每行有若干列。根据列的类型,可以得到它所占用的存储空间,如int占用4个字节,decimal根据长度占用0到4个字节等。这样,可以推算出一行记录占用的空间,再进一步,可以推荐出一张表里的数据占用多大空间。
或者,通过以下SQL,可以查看当前每个库中的数据大小。
SELECT table_schema "Data Base Name",
sum( data_length + index_length ) / 1024 / 1024 "Data Base Size in MB"
FROM information_schema.TABLES
GROUP BY table_schema ;复制
当然了,一个库里,并不是所有的表里的数据都需要进行es索引,所以,还需要把要进行es索引的表整理出来,只估算它们的数据量,或者是估算它们占总数据量的比例。
注意我们只是估算,事实上也完全没必要做的太准确,毕竟如果容量不够,es支持我们随时在集群里增加新的节点。
比如说,对于某商城系统,我们可以简单的认为一条商品数据大概占200kb,数据库里总共有100万条商品,则大概约200GB。
到底需要多少个节点?
有了数据量以后,另一个要参考的数据是,ES jvm 的堆最大可设置为32GB,这样一个节点,一般可以处理10T的数据。也就是说,200GB的数据量,一个节点就够用了。哪怕是商品数增加到了一亿个,那么,20T的数据,也只需要两个节点。当然了,这只是从数据处理能力是否足够的角度去分析的,事实上我们还需要考虑应对高并发和系统的高可用。所以,如果你了解过一些实际的应用,你会发现,一般应用的es集群都基本上是三个节点,每个节点都是数据节点,也是候选主节点。那种专门做搜索或数据分析的公司,可能会达到几十甚至上百个节点,并且,会有专门的候选主节点和客户端节点。
所以,当老板问的时候,你告诉他:三台。这个答案,对于一个刚打算上es的公司来说,基本上是没有问题的。
分片和副本
分片和副本的本质是一样的,存储的都是数据。只是分片是针对一个大块数据而言,要把它进行分开存放。而副本则是要把一份相同的数据进行冗余。分片是为了处理单个节点可能无法完整处理的数据,而副本,则是为了保证数据的安全性,以及提升系统的并发能力。
前面我们聊到,一个32G heap 大小的节点,可以处理约10T数据。但是,如果我们把200G数据一次性发给es,那es就需要先找个地方,把这200G数据装进内存。这时候,32G heap最大也就只能装32G,所以,就需要分片来处理。也就是说,200G可能需要7个或8个分片来处理。
分片后,可以处理的数据量变大,但是,相应的,搜索,聚合等也就需要在多个分片上进行,过多的分片就影响到es的性能。所以,一般来说,分片的数据会设置成节点数据的1.5到3倍。如果数据量过大,导致无法处理的情况,通过客户端进行拆分后分批发送给es。
副本一是提高可用性,二是分担并发。
从提高可用性来说,1~2个副本即可。分担并发来说,根据实际的并发量来设置。副本过多也会影响到es的性能。如果es的数据量不大,但是并发很高,可以考虑增加专门的客户端节点来进行处理。