ToB企服应用市场:ToB评测及商务社交产业平台

标题: 聊聊分布式 SQL 数据库Doris(六) [打印本页]

作者: 欢乐狗    时间: 2024-1-14 15:22
标题: 聊聊分布式 SQL 数据库Doris(六)
负载均衡

此处的负载均衡指的是FE层的负载均衡.
当部署多个 FE 节点时,用户可以在多个 FE 之上部署负载均衡层来实现 Doris 的高可用。官方文档描述: 负载均衡
实现方式

实现方式有多种,如下列举。
开发者在应用层自己进行重试与负载均衡。
JDBC Connector

发现一个连接挂掉,就自动在其他连接上进行重试。应用层代码重试需要应用自己配置多个 doris 前端节点地址。
通过 JDBC Connector实现自动重试与均衡负载:
  1. jdbc:mysql:loadbalance://[host:port],[host:port].../[database][?propertyName1][=propertyValue1][&propertyName2][=propertyValue
复制代码
Proxy SQL

架设一层代理,通过ProxySQL代理层实现负载。
Nginx 反向代理

通过网关反向代理实现负载。
数据倾斜

由于数据在分区或分桶或者是源数据端的数据存储就不均匀,因此在导入到Doris中分布不均匀,导致Doris的性能和稳定性不好。
原因

Doris出现数据倾斜的原因有多种,其中一些常见的原因包括:
解决

为了解决Doris的数据倾斜问题,可以尝试以下方法:
高并发点查

点查: 是指通过等值条件(例如 WHERE 子句中的等值条件)来查询单个行或单个数据点的查询操作。点查询通常用于检索具有特定键值的行或数据,其特点是通过提供唯一的主键值或唯一索引值来定位并返回一行数据/单个数据点。
在高并发服务场景中,如果用户希望从系统中获取整行数据,对于列存格式引擎,在表宽时,列存格式将大大放大随机读取IO,这就会导致读取性能降低;其次,FE层是对外提供的是访问服务,同时会分析、解析SQL,也可能会导致高并发查询时的高CPU开销。为了解决性能问题,引入了行存、短查询路径、PreparedStatement解决。官方文档描述: 高并发点查
行存

仅仅支持在建表时开启行存模式,但需要额外的空间来存储行存数据。实现逻辑是将行存编码后存在单独的一列中,用于简化行存的实现。在create的property中指定属性:
  1. "store_row_column = "true"
复制代码
行存(Row Storage)
列存(Column Storage)
由于列存储是按列存储的,获取整行数据需要从不同列的数据块中进行随机读取,增加了磁盘I/0操作的次数;如果列宽度较大,那么需要读取的数据块数量就会增加,导致随机读取的开销放大;同时较大的列宽导致单个记录的大小较大,需要传输更多的数据量到查询引擎。这会增加网络传输的开销,尤其是在分布式系统中,如果数据分布在多个节点上,点查询可能需要从多个节点传输数据。
Unique 模型下的点查优化

Unique模型支持写入时合并(Merge-On-Write)策略,当开启该策略结合行存时,对于主键的点查会走短路径对SQL执行优化,仅需执行一次RPC查询即可完成。如下示例:
  1. CREATE TABLE `tbl_point_query` (
  2.     `key` int(11) NULL,
  3.     `v1` decimal(27, 9) NULL,
  4.     `v2` varchar(30) NULL,
  5.     `v3` varchar(30) NULL,
  6.     `v4` date NULL,
  7.     `v5` datetime NULL,
  8.     `v6` float NULL,
  9.     `v7` datev2 NULL
  10. ) ENGINE=OLAP
  11. UNIQUE KEY(`key`)
  12. COMMENT 'OLAP'
  13. DISTRIBUTED BY HASH(`key`) BUCKETS 1
  14. PROPERTIES (
  15.     "replication_allocation" = "tag.location.default: 1",
  16.     "enable_unique_key_merge_on_write" = "true",
  17.     "light_schema_change" = "true",
  18.     "store_row_column" = "true"
  19. );
复制代码
注意:
PreparedStatement

Doris在FE层提供了与MySQL协议兼容的PreparedStatement特性(目前只支持主键点查)。当PreparedStatement开启时,SQL与其表达式将被提前计算并缓存到Session级别的内存缓存中,后续的查询直接使用缓存对象即可。
示例:
  1. url = jdbc:mysql://127.0.0.1:9030/ycsb?useServerPrepStmts=true
复制代码
  1. // use `?` for placement holders, readStatement should be reused
  2. PreparedStatement readStatement = conn.prepareStatement("select * from tbl_point_query where key = ?");
  3. ...
  4. readStatement.setInt(1234);
  5. ResultSet resultSet = readStatement.executeQuery();
  6. ...
  7. readStatement.setInt(1235);
  8. resultSet = readStatement.executeQuery();
  9. ...
复制代码
PreparedStatement 支持使用占位符参数(如?)来表示 SQL 语句中的变量部分。在执行语句之前,可以通过设置参数的方式为占位符提供实际的数值。这有助于防止 SQL 注入攻击,并提高安全性。
开启行缓存

对于前面提到的行存,一行里包括了多列数据,Doris默认支持的列缓存可能被大查询给刷掉,为了增加行缓存命中率,单独引入了行存缓存,行缓存复用了 Doris 中的 LRU Cache 机制来保障内存的使用,通过指定下面的的BE配置来开启

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4