一、维表join基础操作
在实际工作场景中,数据流处理往往需要与相关的维度数据进行关联操作。根据不同的业务场景和需求,合理选择相应的缓存策略至关重要,以确保数据处理的效率和准确性。
通用缓存策略详解
在使用维表 Join 时,大部分连接器都支持缓存策略,但不同连接器对缓存策略的支持情况可能略有不同。因此,在使用缓存策略之前,请务必查阅对应连接器的官方文档,以确定具体的支持情况。以下是通用的缓存策略及其详细说明:
1. None(默认值):无缓存
描述:不使用任何缓存机制,每次查询都直接从物理维表中获取数据。
使用场景:
对数据准确性要求极高,无法容忍任何数据延迟或不准确的情况。
维表数据更新频繁,实时性要求高。
优点:
数据实时性强,能够保证查询结果的准确性。
缺点:
当数据量较大时,Join 操作的性能压力会显著增加,容易导致反压。
对维表数据库的查询压力较大,可能影响数据库性能。
2. LRU(Least Recently Used):缓存部分数据
描述:缓存维表中的部分数据。系统会根据最近使用情况维护一个缓存,源表的每条数据都会先在缓存中查找,如果未找到,则从物理维表中查询。
使用场景:
维表数据更新频率较低,可以容忍少量数据不准确的情况。
对查询性能有一定要求,但对数据实时性要求不高。
优点:
提高 Join 操作的性能,减少对物理维表的查询次数。
缓存机制可以有效缓解数据库的压力。
缺点:
当维表数据发生变化时,缓存中的部分数据可能会变得不准确。
缓存大小有限,可能导致部分数据无法被缓存。
3. ALL:缓存全部数据
描述:缓存维表中的所有数据。在作业运行前,系统会将维表中的所有数据加载到缓存中,之后所有的维表查找操作都会通过缓存进行。如果在缓存中未找到数据,则认为该键不存在。全量缓存有一个过期时间,过期后会重新加载全量缓存。
使用场景:
适用于远程表数据量较小,且源表数据与维表 JOIN 时,ON 条件无法关联(MISS KEY)的情况较多。
对查询性能要求极高,且可以接受全量数据加载的延迟。
优点:
提供最高的查询性能,因为所有数据都在缓存中。
减少了对物理维表的查询,降低了数据库的压力。
缺点:
缓存占用内存较大,可能需要较多的资源。
数据更新后,需要等待缓存过期或手动刷新缓存,可能存在短暂的数据不一致。
目前维表关联伪代码如下:
--数据源
CREATE TEMPORARY TABLE tmp (
driver_id bigint,
lng double precision,
lat double precision,
speed double precision,
proctime as PROCTIME()
)
WITH (
'connector' = 'mysql', --连接器的标示
'dbname' = '',
'tablename' = '',
'username' = '',
'password' = '',
'endpoint' = ''
);
--维表
CREATE TEMPORARY TABLE dim_tmp (
driver_id bigint,
driver_value VARCHAR,
PRIMARY KEY(driver_id) not ENFORCED
)
WITH (
'connector' = 'redis',
'host' = '',
'port' = '6379',
'password' = '',
'cache' = 'LRU', --缓存
'cacheSize' = '100000',--缓存数据量
'cacheTTLMs' = '0',--时效
'dbNum' = '4'
);
--维表join
select
t.driver_id
,t2.driver_value
FROM tmp t1
LEFT JOIN dim_tmp FOR SYSTEM_TIME AS OF t1.proctime AS t2
ON t1.driver_id = t2.driver_id
二、维表join 策略
Lookup Hints
| 场景 | 策略 |
|
配置'shuffle' = 'true'选项 |
使用引擎默认的shuffle策略。 |
|
不配置'shuffle' = 'true'选项,且维表连接器不提供自定义联接策略 | |
|
配置'shuffle' = 'true' 选项,且维表连接器不提供自定义联接策略 |
默认使用SHUFFLE_HASH策略 |
|
配置'shuffle' = 'true' 选项,且维表连接器提供自定义联接策略 |
使用表连接器的自定义shuffle策略。 |
对维表配置联接时的shuffle策略代码示例如下:
--维表join
select /*+ LOOKUP('table'='t2', 'shuffle' = 'true'),LOOKUP('table'='t3', 'shuffle' = 'true') */
t.driver_id
,t2.driver_value
FROM tmp t1
LEFT JOIN dim_tmp FOR SYSTEM_TIME AS OF t1.proctime AS t2
ON t1.driver_id = t2.driver_id
LEFT JOIN dim_tmp_1 FOR SYSTEM_TIME AS OF t1.proctime AS t3
ON t1.driver_id = t3.driver_id
其他Join Hints
维表Join Hints仅用于配置维表联接策略,包括SHUFFLE_HASH、REPLICATED_SHUFFLE_HASH和SKEW。维表Cache策略和联接策略之间的适用场景详情如下表所示。
|
Cache策略 |
SHUFFLE_HASH |
REPLICATED_SHUFFLE_HASH (和SKEW等价) |
|
None |
不建议使用该联接策略提示,主流会引入额外的网络开销。 |
不建议使用该联接策略提示,主流会引入额外的网络开销。 |
|
LRU |
在维表查找IO成为瓶颈时,建议考虑使用该联接策略提示。当主流数据在Join Key上有时间局部性时,可以提高Cache命中率,减少IO请求数,从而提升总吞吐。 重要 主流会引入额外的网络开销,当主流数据在Join Key上有倾斜,遇到性能瓶颈时,建议考虑REPLICATED_SHUFFLE_HASH。 |
在维表查找IO成为瓶颈且主流数据在Join Key上有倾斜时,建议考虑该联接策略提示。当主流数据在Join Key上有时间局部性时,可以提高Cache命中率,减少IO请求数,从而提升总吞吐。 |
|
ALL |
在维表内存使用量成为瓶颈时,建议使用该联接策略提示。内存使用率可降低为1/并发度。 重要 主流会引入额外的网络开销,当主流数据在Join Key上有倾斜,遇到性能瓶颈时,建议考虑REPLICATED_SHUFFLE_HASH。 |
在维表内存使用量成为瓶颈且主流数据在Join Key上有倾斜时,建议使用该联接策略提示。内存使用率降低为分桶数/并发度。 |
SHUFFLE_HASH
使用效果
在维表Join中使用Shuffle Hash策略,可以将主流数据在Join之前根据Join Key做一次shuffle。在使用LRU Cache策略时可以提高Cache命中率,减少IO请求数;在使用ALL Cache策略时可以减少内存使用量。每个SHUFFLE_HASH联接提示可指定多张维表。
使用限制
虽然SHUFFLE_HASH可以减少内存开销,但是由于上游数据需要按照Join Key做一次shuffle,引入额外的网络开销,因此下面两种场景不适合使用SHUFFLE_HASH联接策略。
主流数据在Join Key上存在严重的数据倾斜,这种场景下如果使用SHUFFLE_HASH联接,会因为数据倾斜导致Join节点成为性能瓶颈,从而会导致流作业出现严重反压或是批场景出现严重长尾,此时建议使用REPLICATED_SHUFFLE_HASH联接。
维表数据较小,ALL Cache策略加载没有内存瓶颈时,如果使用SHUFFLE_HASH联接,节约的内存开销和额外引入的网络开销相比,可能并不划算。
代码示例:
--维表join
select /*+ SHUFFLE_HASH(t2, t3) */
t.driver_id
,t2.driver_value
FROM tmp t1
LEFT JOIN dim_tmp FOR SYSTEM_TIME AS OF t1.proctime AS t2
ON t1.driver_id = t2.driver_id
LEFT JOIN dim_tmp_1 FOR SYSTEM_TIME AS OF t1.proctime AS t3
ON t1.driver_id = t3.driver_id
REPLICATED_SHUFFLE_HASH
使用效果
在维表Join中使用Replicated Shuffle Hash策略,其效果基本与SHUFFLE_HASH一致,但不同点是其会将主流具有相同key的数据随机打散到指定的N个并发上,可以解决数据倾斜导致的性能瓶颈。每个REPLICATED_SHUFFLE_HASH联接提示中可指定多张维表。
使用限制
需要配置倾斜数据分桶数量参数
table.exec.skew-join.replicate-num,其默认值为16,取值不能大于维表联接节点的并发。当前不支持更新流,当主流是更新流时,使用REPLICATED_SHUFFLE_HASH策略会报错。
代码示例:
--维表join
select /*+ REPLICATED_SHUFFLE_HASH(t2) */
t.driver_id
,t2.driver_value
FROM tmp t1
LEFT JOIN dim_tmp FOR SYSTEM_TIME AS OF t1.proctime AS t2
ON t1.driver_id = t2.driver_id
SKEW
使用效果
当指定表存在数据倾斜时,优化器会在维表Join中使用Replicated Shuffle Hash策略(Skew只是一个语法糖,底层的实现是用的Replicated Shuffle Hash策略)。
使用限制
每个SKEW提示只能指定1张表。
表名需要为存在数据倾斜的主表名称,而不是维表名称。
当前不支持更新流,当主流是更新流时,使用SKEW策略会报错。
代码示例:
--维表join
select /*+ SKEW(t1) */
t.driver_id
,t2.driver_value
FROM tmp t1
LEFT JOIN dim_tmp FOR SYSTEM_TIME AS OF t1.proctime AS t2
ON t1.driver_id = t2.driver_id
⚠️重要
当前LOOKUP Hint的shuffle选项已能覆盖 SHUFFLE_HASH hint功能,两者同时使用时,会优先采纳LOOKUP hint的shuffle选项。
当前LOOKUP Hint的shuffle选项还未支持解决数据倾斜的功能,当和REPLICATED_SHUFFLE_HASH、SKEW同时使用时,会优先采纳REPLICATED_SHUFFLE_HASH、SKEW对应的shuffle策略。
4405



被折叠的 条评论
为什么被折叠?



