DevilKing's blog

冷灯看剑,剑上几分功名?炉香无需计苍生,纵一穿烟逝,万丈云埋,孤阳还照古陵

0%

分布式请求查询

Data centric分布式查询优化

  1. 客户端的路由优化:能根据分布式执行计划以及请求数据优化路由节点的选取策略
  2. 服务端的执行优化:根据数据(窗口数据分布特性)在尽可能优的节点(local)执行。(未来可能可以考虑在同机房等因素)
  3. 任务并行调度优化:没有依赖关系的节点可以并行执行。

原文链接

image-20200921111204220

采用 Flink+Kudu 的方案主要思想是借鉴了 Kylin 的思路,Kylin 可以指定很多维度和指标进行离线的预计算然后将预计算结果存储到 Hbase 中;快手的方案是通过 Flink 实时计算指标,再实时地写到 Kudu 里面。

这块关于统计的降级维度是?

因此快手设计了两层降维计算模型,分为全维度层和剩余维度层,这样既利用了全维度层的聚合结果又简化了 DAG 作业图。

全维度部分,通过bitmap的引入,将相关string转为为long,量级大了之后,再辅以bitmapstate进行拆分

Kudu 里面,其本身具有低延迟随机读写以及快速列扫描等特点,很适合实时交互分析场景;

在存储方式上,首先对维度进行编码,然后按时间+维度组合+维度值组合作为主键,

最终按维度组合、维度值组合、时间进行分区,这样有利于提高查询的效率快速获取到数据。

面临着磁盘 IO 开销70%,其中50%开销来自于 Compaction;在 Checkpoint 期间,磁盘 IO 开销达到了100%,耗时在1~5分钟,甚至会长于 Checkpoint 间隔,业务能明显感觉到反压。

利用hbase来替代rockdb,一则是共享存储部分,同时,可以支持多种campaction策略,

SlimBase

HBase 瘦身,主要从减肥和增瘦两个步骤,在减肥方面:

  • 先对 HBase 进行减裁,去除 client、zookeeper 和 master,仅保留 RegionServer
  • 再对 RegionServer 进行剪裁,去除 ZK Listener、Master Tracker、Rpc、WAL 和 MetaTable
  • 仅保留 RegionServer 中的 Cache、Memstore、Compaction、Fluster 和 Fs

目前用的 Compaction 策略是 SizeTieredCompaction,后期要实现基于 OldestUnexpiredTime 的 FiFOCompaction 策略,目标是做到无磁盘 IO 开销。

FiFOCompaction 是一种基于 TTL 的无 IO 的 Compaction 策略;OldestUnexpiredTime 是指例如设置 OldestUnexpiredTime=t2,表示 t2 时刻前的数据全部过期,可以被 Compaction 清理,基于时间点的 FIFOCompaction 理论上可以做到无磁盘 IO 开销。

与MySQL相比具有以下优势:

  1. MemSQL是一个分布式可扩展的系统,可以轻松扩展到上千台机器的规模
  2. 没有buffer pool。传统的数据库会使用一个buffer pool, 因为他们不能把所有数据都放到内存中。所有db和表共享一个buffer pool,这样就会导致明显的竞争
  3. Lock-free的数据结构。MemSQL试用了基于内存优化的、lock-free的 skiplist和hash table作为索引。相比b-tree这些数据结构在内存中运行的更快
  4. Code generation. MemSQL把sql编译成native code提供更好的性能

从memsql5开始使用llvm来做code generation

关于code generation的主流部分?

一个MemSQL包含两种组件:

  1. Aggregator nodes负责处理分布式系统中的metadata, query路由,结果整合。依据请求规模,一个集群中可以有一个或者多个aggregators. 其中有一个是master aggregator用来维护metadata,集群监控和failover.
  2. Leaf nodes存储数据和执行sql查询。一个leaf节点是一个memsql server实例,包含多个partition.

aggregator部分,也有master和slave节点的区别,

reference tables的概念,类似spark broadcast部分?

分片的层级部分,partition部分切分,如何进行,如何更好通过使用的方式来优化策略

原文链接

Implicit type conversion

一些规则:

  • 两个参数至少有一个是 NULL 时,比较的结果也是 NULL,例外是使用 <=> 对两个 NULL 做比较时会返回 1,这两种情况都不需要做类型转换
  • 两个参数都是字符串,会按照字符串来比较,不做类型转换
  • 两个参数都是整数,按照整数来比较,不做类型转换
  • 十六进制的值和非数字做比较时,会被当做二进制串
  • 有一个参数是 TIMESTAMPDATETIME,并且另外一个参数是常量,常量会被转换为 timestamp
  • 有一个参数是 decimal 类型,如果另外一个参数是 decimal 或者整数,会将整数转换为 decimal 后进行比较,如果另外一个参数是浮点数,则会把 decimal 转换为浮点数进行比较
  • 所有其他情况下,两个参数都会被转换为浮点数再进行比较
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mysql> select '55aaa' = 55;
+--------------+
| '55aaa' = 55 |
+--------------+
| 1 |
+--------------+
1 row in set, 1 warning (0.00 sec)

mysql> select 'a' + '55';
+------------+
| 'a' + '55' |
+------------+
| 55 |
+------------+
1 row in set, 1 warning (0.00 sec)

可以登录系统

1
SELECT * FROM users WHERE username = 'a' OR 1='1' AND password = 'anyvalue'

主要是针对字符串部分

隐式转化把字符串转为了double类型。但是因为字符串是非数字型的,所以就会被转换为0,因此最终计算的是0+1=1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mysql> select 'a'+'b'='c';
+-------------+
| 'a'+'b'='c' |
+-------------+
| 1 |
+-------------+
1 row in set, 3 warnings (0.00 sec)

mysql> show warnings;
+---------+------+---------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: 'a' |
| Warning | 1292 | Truncated incorrect DOUBLE value: 'b' |
| Warning | 1292 | Truncated incorrect DOUBLE value: 'c' |
+---------+------+---------------------------------------+
3 rows in set (0.00 sec)

这样当进行select,update或者delete的时候就可能会多操作一些数据。所以应该加引号的地方别忘记了。

当把字符串转为数字的时候,其实是从左边开始处理的。

  • 如果字符串的第一个字符就是非数字的字符,那么转换为数字就是0
  • 如果字符串以数字开头
  • 如果字符串中都是数字,那么转换为数字就是整个字符串对应的数字
  • 如果字符串中存在非数字,那么转换为的数字就是开头的那些数字对应的值