云服务器内容精选

  • 原因分析 GaussDB (DWS)支持Hash、REPLICATION和ROUNDROBIN(8.1.2集群及以上版本支持ROUNDROBIN)分布方式。如果创建了Hash分布的表,未指定分布键,则选择表的第一列作为分布键,这种情况就可能存在倾斜。倾斜造成以下负面影响: SQL的性能会非常差,因为数据只分布在部分DN,那么SQL运行的时候就只有部分DN参与计算,没有发挥分布式的优势。 会导致资源倾斜,尤其是磁盘。可能部分磁盘的空间已经接近极限,但是其他磁盘利用率很低。 可能出现部分节点CPU过高等问题。
  • 原因分析 SQL运行慢可从以下几方面进行分析: 使用EXPLAIN命令查看SQL执行计划,根据执行计划判断是否需要进行SQL调优。 分析查询是否被阻塞,导致语句运行时间过长,可以强制结束有问题的会话。 审视和修改表定义。选择合适的分布列,避免数据倾斜。 分析SQL语句是否使用了不下推的函数,建议更换为支持下推的语法或函数。 对表定期执行VACUUM FULL和ANALYZE操作,可回收已更新或已删除的数据所占据的磁盘空间。 检查表有无索引支撑,建议例行重建索引。 数据库经过多次删除操作后,索引页面上的索引键将被删除,造成索引膨胀。例行重建索引,可有效的提高查询效率。 对业务进行优化,分析能否将大表进行分表设计。
  • 解决办法 通过下列的操作步骤,可以分析出查询效率异常降低的原因。 使用ANALYZE命令分析数据库。 ANALYZE命令更新所有表中数据大小以及属性等相关统计信息,该命令较为轻量级,可以经常执行。如果此命令执行后性能恢复或者有所提升,则表明AUTOVACUUM未能很好的完成它的工作,有待进一步分析。 检查查询语句是否返回了多余的数据信息。 例如,如果查询语句先查询一个表中所有的记录,而只用到结果中的前10条记录。对于包含50条记录的表,查询起来是很快的;但是,当表中包含的记录达到50000,查询效率将会有所下降。 若业务应用中存在只需要部分数据信息,但是查询语句却是返回所有信息的情况,建议修改查询语句,增加LIMIT子句来限制返回的记录数。这样至少使数据库优化器有了一定的优化空间,一定程度上会提升查询效率。 检查查询语句单独运行时是否仍然较慢。 尝试在数据库没有其他查询或查询较少的时候运行查询语句,并观察运行效率。如果效率较高,则说明可能是由于之前运行数据库系统的主机负载过大导致查询低效。此外,还可能是由于执行计划比较低效,但是由于主机硬件较快使得查询效率较高。 检查重复相同查询语句的执行效率。 查询效率低的一个重要原因是查询所需信息没有缓存在内存中,这可能是由于内存资源紧张,缓存信息被其他查询处理覆盖。 重复执行相同的查询语句,如果后续执行的查询语句效率提升,则可能是由于上述原因导致。
  • 写入性能优化 基于Elasticsearch的数据写入流程分析,有以下几种性能优化方案。 表1 写入性能优化 优化方案 方案说明 使用SSD盘或升级集群配置 使用SSD盘可以大幅提升数据写入与merge操作的速度,对应到 CSS 服务,建议选择“超高IO型”存储,或者超高IO型主机。 采用Bulk API 客户端采用批量数据的写入方式,每次批量写入的数据建议在1~10MB之间。 随机生成_id 如果采用指定_id的写入方式,数据写入时会先触发一次查询操作,进而影响数据写入性能。对于不需要通过_id检索数据的场景,建议使用随机生成的_id。 设置合适的分片数 分片数建议设置为集群数据节点的倍数,且分片的大小控制在50GB以内。 关闭副本 数据写入与查询错峰执行,在数据写入时关闭数据副本,待数据写入完成后再开启副本。 Elasticsearch 7.x版本中关闭副本的命令如下: PUT {index}/_settings { "number_of_replicas": 0 } 调整索引的刷新频率 数据批量写入时,可以将索引的刷新频率“refresh_interval”设置为更大的值或者设置为“-1”(表示不刷新),通过减少分片刷新次数提高写入性能。 Elasticsearch 7.x版本中,将更新时间设置为15s的命令如下: PUT {index}/_settings { "refresh_interval": "15s" } 优化写入线程数与写入队列大小 为应对突发流量,可以适当地提升写入线程数与写入队列的大小,防止突发流量导致出现错误状态码为429的情况。 Elasticsearch 7.x版本中,可以修改如下自定义参数实现写入优化:thread_pool.write.size,thread_pool.write.queue_size。 设置合适的字段类型 指定集群中各字段的类型,防止Elasticsearch默认将字段猜测为keyword和text的组合类型,增加不必要的数据量。其中keyword用于关键词搜索,text用于全文搜索。 对于不需要索引的字段,建议“index”设置为“false”。 Elasticsearch 7.x版本中,将字段“field1”设置为不建构索引的命令如下: PUT {index} { "mappings": { "properties": { "field1":{ "type": "text", "index": false } } } } 优化shard均衡策略 Elasticsearch默认采用基于磁盘容量大小的Load balance策略,在多节点场景下,尤其是在新扩容的节点上,可能出现shard在各节点上分配不均的问题。为避免这类问题,可以通过设置索引级别的参数“routing.allocation.total_shards_per_node”控制索引分片在各节点的分布情况。此参数可以在索引模板中配置,也可以修改已有索引的setting生效。 修改已有索引的setting的命令如下: PUT {index}/_settings { "index": { "routing.allocation.total_shards_per_node": 2 } }
  • 数据写入流程 图1 数据写入流程 如图1所示,以Elasticsearch集群为例,介绍客户端往Elasticsearch或OpenSearch集群中写入数据的流程。图中的P表示主分片Primary,R表示副本分片Replica,主副分片在数据节点Node里是随机分配的,但是不能在同一个节点里。 客户端向Node1发送写数据请求,此时Node1为协调节点。 节点Node1根据数据的_id将数据路由到分片2,此时请求会被转发到Node3,并执行写操作。 当主分片写入成功后,它将请求转发到Node2的副本分片上。当副本写入成功后,Node3将向协调节点报告写入成功,协调节点向客户端报告写入成功。 Elasticsearch中的单个索引由一个或多个分片(shard)组成,每个分片包含多个段(Segment),每一个Segment都是一个倒排索引。 图2 Elasticsearch的索引组成 如图3所示,将文档插入Elasticsearch时,文档首先会被写入缓冲区Buffer中,同时写入日志Translog中,然后在刷新时定期从该缓冲区刷新文档到Segment中。刷新频率由refresh_interval参数控制,默认每1秒刷新一次。更多写入性能相关的介绍请参见Elasticsearch的官方介绍Near Real-Time Search。 图3 文档插入Elasticsearch的流程