火山引擎在行为分析场景下的 ClickHouse JOIN 优化_ 字节跳动技术团队的博客-CSDN博客


本站和网页 https://blog.csdn.net/ByteDanceTech/article/details/126716600 的作者无关,不对其内容负责。快照谨为网络故障时之索引,不代表被搜索网站的即时页面。

火山引擎在行为分析场景下的 ClickHouse JOIN 优化_ 字节跳动技术团队的博客-CSDN博客
火山引擎在行为分析场景下的 ClickHouse JOIN 优化
字节跳动技术团队
于 2022-09-05 12:00:52 发布
1089
收藏
文章标签:
分布式
大数据
数据库
python
mysql
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/ByteDanceTech/article/details/126716600
版权
动手点关注 干货不迷路 👇
1. 背景
火山引擎增长分析 DataFinder 基于 ClickHouse 来进行行为日志的分析,ClickHouse 的主要版本是基于社区版改进开发的字节内部版本。主要的表结构:
事件表:存储用户行为数据,以用户 ID 分 shard 存储。
--列出了主要的字段信息
  CREATE TABLE tob_apps_all
  (
      `tea_app_id`                UInt32,  --应用ID
      `device_id`             String DEFAULT '', --设备ID
      `time`                  UInt64,--事件日志接受时间
      `event`                 String,--事件名称
      `user_unique_id`        String,--用户ID
      `event_date`            Date , --事件日志日期,由time转换而来
      `hash_uid`              UInt64 --用户ID hash过后的id,用来join降低内存消耗
  )│
  ```
用户表:存储用户的属性数据,以用户 ID 分 shard 存储。
--列出了主要的字段信息
CREATE TABLE users_unique_all
    `tea_app_id`            UInt32,            --应用ID
    `user_unique_id`        String DEFAULT '', -- 用户ID
    `device_id`             String DEFAULT '', -- 用户最近的设备ID
    `hash_uid`              UInt64,--用户ID hash过后的id,用来join降低内存消耗
    `update_time`           UInt64,--最近一次更新时间
    `last_active_date`      Date  --用户最后活跃日期
设备表:存储设备相关的数据,以设备 ID 分 shard 存储。
--列出了主要的字段信息
CREATE TABLE devices_all
    `tea_app_id`            UInt32,            --应用ID
    `device_id`             String DEFAULT '', --设备ID    
    `update_time`           UInt64,            --最近一次更新时间
    `last_active_date`      Date  --用户最后活跃日期
业务对象表:存储业务对象相关的数据,每个 shard 存储全量的数据。
--列出了主要的字段信息
CREATE TABLE rangers.items_all
    `tea_app_id`            UInt32,
    `hash_item_id`          Int64,
    `item_name`             String, --业务对象名称。比如商品
    `item_id`               String, --业务对象ID。比如商品id 1000001
    `last_active_date`      Date
1.1 业务挑战
随着接入应用以及应用的 DAU 日益增加,ClickHouse 表的事件量增长迅速;并且基于行为数据需要分析的业务指标越来越复杂,需要 JOIN 的表增多;我们遇到有一些涉及到 JOIN 的复杂 SQL 执行效率低,内存和 CPU 资源占用高,导致分析接口响应时延和错误率增加。
2. 关于 Clickhouse 的 JOIN
在介绍优化之前,先介绍一下基本的 ClickHouse JOIN 的类型和实现方式。
2.1 分布式 JOIN
SELECT 
    et.os_name, 
    ut.device_id AS user_device_id
FROM tob_apps_all AS et 
ANY LEFT JOIN 
    SELECT 
        device_id, 
        hash_uid
    FROM users_unique_all 
    WHERE (tea_app_id = 268411) AND (last_active_date >= '2022-08-06')
) AS ut ON et.hash_uid = ut.hash_uid
WHERE (tea_app_id = 268411) 
AND (event = 'app_launch') 
AND (event_date = '2022-08-06')
基本执行过程:
一个 Clickhouse 节点作为 Coordinator 节点,给每个节点分发子查询,子查询 sql(tob_apps_all 替换成本地表,users_unique_all 保持不变依然是分布式表)。每个节点执行 Coordinator 分发的 sql 时,发现 users_unique_all 是分布式表,就会去所有节点上去查询以下 SQL(一共有 N*N。N 为 shard 数量)。
SELECT device_id, hash_uid FROM users_unique WHERE (tea_app_id = 268411) AND (last_active_date >= '2022-08-06')每个节点从其他 N-1个节点拉取2中子查询的全部数据,全量存储(内存 or 文件) ,进行本地 JOIN。Coordinator 节点从每个节点拉取3中的结果集,然后做处理返回给 client。
存在的问题:
子查询数量放大。每个节点都全量存储全量的数据。
2.2 分布式 Global JOIN
SELECT 
    et.os_name, 
    ut.device_id AS user_device_id
FROM tob_apps_all AS et 
GLOBAL ANY LEFT JOIN 
    SELECT 
        device_id, 
        hash_uid
    FROM users_unique_all 
    WHERE (tea_app_id = 268411) AND (last_active_date >= '2022-08-06')
) AS ut ON et.hash_uid = ut.hash_uid
WHERE (tea_app_id = 268411) 
AND (event = 'app_launch') 
AND (event_date = '2022-08-06')
基本执行过程:
一个 Clickhouse 节点作为 Coordinator 节点,分发查询。在每个节点上执行sql(tob_apps_all 替换成本地表,右表子查询替换成别名 ut)。Coordinator 节点去其他节点拉取 users_unique_all 的全部数据,然后分发到全部节点(作为1中别名表 ut 的数据)。每个节点都会存储全量的2中分发的数据(内存or文件),进行本地 local join。Coordinator 节点从每个节点拉取3中的结果集,然后做处理返回给 client。
存在的问题:
每个节点都全量存储数据。如果右表较大,分发的数据较大,会占用网络带宽资源。
2.3 本地 JOIN
SQL 里面只有本地表的 JOIN,只会在当前节点执行。
SELECT et.os_name,ut.device_id AS user_device_id
FROM tob_apps et any LEFT JOIN
    (SELECT device_id,
         hash_uid
    FROM rangers.users_unique
    WHERE tea_app_id = 268411
            AND last_active_date>='2022-08-06') ut
    ON et.hash_uid=ut.hash_uid
WHERE tea_app_id = 268411
        AND event='app_launch'
        AND event_date='2022-08-06'
2.3.1 Hash join
右表全部数据加载到内存,再在内存构建 hash table。key 为 joinkey。从左表分批读取数据,从右表 hash table匹配数据。优点是:速度快 缺点是:右表数据量大的情况下占用内存。
3.3.2 Merge join‍
对右表排序,内部 block 切分,超出内存部分 flush 到磁盘上,内存大小通过参数设定。左表基于 block 排序,按照每个 block 依次与右表 merge。优点是:能有效控制内存 缺点是:大数据情况下速度会慢。
优先使用 hash join 当内存达到一定阈值后再使用 merge join,优先满足性能要求。
3. 解决方案
3.1 避免JOIN
3.1.1 数据预生成
数据预生成(由 Spark/Flink 或者 Clickhouse 物化视图产出数据),形成大宽表,基于单表的查询是 ClickHouse 最为擅长的场景。
我们有个指标,实现的 SQL 比较复杂(如下),每次实时查询很耗时,我们单独建了一个表 table,由 Spark 每日构建出这个指标,查询时直接基于 table 查询。
SELECT event_date,count(distinct uc1) AS uv,sum(value) AS sum_value, ......
FROM
    (SELECT event_date,hash_uid AS uc1,sum(et.float_params{ 'amount' }) AS value, count(1) AS cnt, value*cnt AS multiple
    FROM tob_apps_all et GLOBAL  ANY  LEFT  JOIN
(SELECT hash_uid AS join_key,int_profiles{ '$ab_time_34' }*1000 AS first_time
        FROM users_unique_all
        WHERE app_id = 10000000 AND last_active_date >= '2022-07-19'  AND first_time is  NOT  null) upt
            ON et.hash_uid=upt.join_key
        WHERE (查询条件)
        GROUP  BY uc1,event_date)
GROUP  BY event_date;
数据量2300W,查询时间由7秒->0.008秒。当然这种方式,需要维护额外的数据构建任务。总的思路就是不要让 ClickHouse 实时去 JOIN。
3.1.2 使用 IN 代替 JOIN
JOIN 需要基于内存构建 hash table 且需要存储右表全部的数据,然后再去匹配左表的数据。而 IN 查询会对右表的全部数据构建 hash set,但是不需要匹配左表的数据,且不需要回写数据到 block。
比如:
SELECT event_date, count()
FROM tob_apps_all et global any INNER JOIN
    (SELECT hash_uid AS join_key
    FROM users_unique_all
    WHERE app_id = 10000000
            AND last_active_date >= '2022-01-01') upt
    ON et.hash_uid = upt.join_key
WHERE app_id = 10000000
        AND event_date >= '2022-01-01'
        AND event_date <= '2022-08-02'
GROUP BY  event_date
可以改成如下形式:
SELECT event_date,
         count()
FROM tob_apps_all
WHERE app_id = 10000000
        AND event_date >= '2022-01-01'
        AND event_date <= '2022-08-02'
        AND hash_uid global IN 
    (SELECT hash_uid
    FROM users_unique_all
    WHERE (tea_app_id = 10000000)
            AND (last_active_date >= '2022-01-01') )
 GROUP BY event_date
如果需要从右表提取出属性到外层进行计算,则不能使用 IN 来代替 JOIN。
相同的条件下,上面的测试 SQL,由 JOIN 时的16秒优化到了 IN 查询时的11秒。
3.2 更快的 JOIN
3.2.1 优先本地 JOIN
数据预先相同规则分区
也就是 Colocate JOIN。优先将需要关联的表按照相同的规则进行分布,查询时就不需要分布式的 JOIN。
SELECT 
    et.os_name, 
    ut.device_id AS user_device_id
FROM tob_apps_all AS et 
ANY LEFT JOIN 
    SELECT 
        device_id, 
        hash_uid
    FROM users_unique_all 
    WHERE (tea_app_id = 268411) AND (last_active_date >= '2022-08-06')
) AS ut ON et.hash_uid = ut.hash_uid
WHERE (tea_app_id = 268411) 
AND (event = 'app_launch') 
AND (event_date = '2022-08-06')
settings distributed_perfect_shard=1
比如事件表 tob_apps_all 和用户表 users_unique_all 都是按照用户 ID 来分 shard 存储的,相同的用户的两个表的数据都在同一个 shard 上,因此这两个表的 JOIN 就不需要分布式 JOIN 了。
distributed_perfect_shard 这个 settings key 是字节内部 ClickHouse 支持的,设置过这个参数,指定执行计划时就不会再执行分布式 JOIN 了。
基本执行过程:
一个 ClickHouse 节点作为 Coordinator 节点,分发查询。在每个节点上执行 sql(tob_apps_all、users_unique_all替换成本地表)。每个节点都执行1中分发的本地表 join 的 SQL(这一步不再分发右表全量的数据)。数据再回传到 coordinator 节点,然后返回给 client。
数据冗余存储
如果一个表的数据量比较小,可以不分 shard 存储,每个 shard 都存储全量的数据,例如我们的业务对象表。查询时,不需要分布式 JOIN,直接在本地进行 JOIN 即可。
SELECT count()
FROM tob_apps_all AS et 
ANY LEFT JOIN 
    SELECT item_id
    FROM items_all 
    WHERE (tea_app_id = 268411)
) AS it ON et.item_id = it.item_id
WHERE (tea_app_id = 268411) 
AND (event = 'app_launch') 
AND (event_date = '2022-08-06')
settings distributed_perfect_shard=1
例如这个 SQL,items_all 表每个 shard 都存储同样的数据,这样也可以避免分布式 JOIN 带来的查询放大和全表数据分发问题。
3.2.2 更少的数据
不论是分布式 JOIN 还是本地 JOIN,都需要尽量让少的数据参与 JOIN,既能提升查询速度也能减少资源消耗。
SQL 下推
ClickHouse 对 SQL 的下推做的不太好,有些复杂的 SQL 下推会失效。因此,我们手动对 SQL 做了下推,目前正在测试基于查询优化器来帮助实现下推优化,以便让 SQL 更加简洁。
下推的 SQL:
SELECT 
    et.os_name, 
    ut.device_id AS user_device_id
FROM tob_apps_all AS et 
ANY LEFT JOIN 
    SELECT 
        device_id, 
        hash_uid
    FROM users_unique_all 
    WHERE (tea_app_id = 268411) 
        AND (last_active_date >= '2022-08-06'
        AND 用户属性条件 1  OR 用户属性条件 2)
) AS ut ON et.hash_uid = ut.hash_uid
WHERE (tea_app_id = 268411) 
AND (event = 'app_launch') 
AND (event_date = '2022-08-06')
settings distributed_perfect_shard=1
对应的不下推的 SQL:
SELECT 
    et.os_name, 
    ut.device_id AS user_device_id
FROM tob_apps_all AS et 
ANY LEFT JOIN 
    SELECT 
        device_id, 
        hash_uid
    FROM rangers.users_unique_all 
    WHERE (tea_app_id = 268411) 
        AND (last_active_date >= '2022-08-06')
) AS ut ON et.hash_uid = ut.hash_uid
WHERE (tea_app_id = 268411) 
AND (event = 'app_launch') 
AND (event_date = '2022-08-06')
AND (ut.用户属性条件 1  OR ut.用户属性条件 2)
settings distributed_perfect_shard=1
可以看到,不下推的 SQL 更加简洁,直接基于 JOIN 过后的宽表进行过滤。但是 ClickHouse 可能会将不满足条件的 users_unique_all 数据也进行 JOIN。
我们使用中有一个复杂的 case,用户表过滤条件不下推有1千万+,SQL 执行了3000秒依然执行超时,而做了下推之后60秒内就执行成功了。
3.2.3 Clickhouse 引擎层优化
一个 SQL 实际在 Clickhouse 如何执行,对 SQL 的执行时间和资源消耗至关重要。社区版的 Clickhouse 在执行模型和 SQL 优化器上还要改进的空间,尤其是复杂 SQL 以及多 JOIN 的场景下。
执行模型优化
社区版的 Clickhouse 目前还是一个两阶段执行的执行模型。第一阶段,Coordinator 在收到查询后,将请求发送给对应的 Worker 节点。第二阶段,Worker 节点完成计算,Coordinator 在收到各 Worker 节点的数据后进行汇聚和处理,并将处理后的结果返回。
有以下几个问题:
第二阶段的计算比较复杂时,Coordinator 的节点计算压力大,容易成为瓶颈。不支持 shuffle join,hash join 时右表为大表时构建慢,容易 OOM。对复杂查询的支持不友好。
字节跳动 ClickHouse 团队为了解决上述问题,改进了执行模型,参考其他的分布式数据库引擎(例如 Presto 等),将一个复杂的 Query 按数据交换情况切分成多个 Stage,各 Stage 之间则通过 Exchange 完成数据交换。根据 Stage 依赖关系定义拓扑结构,产生 DAG 图,并根据 DAG 图调度 Stage。例如两表 JOIN,会先调度左右表读取 Stage,之后再调度 JOIN 这个 Stage, JOIN 的 Stage 依赖于左右表的 Stage。
举个例子
SELECT 
    et.os_name, 
    ut.device_id AS user_device_id, 
    dt.hash_did AS device_hashid
FROM tob_apps_all AS et 
GLOBAL ANY LEFT JOIN 
    SELECT 
        device_id, 
        hash_uid
    FROM users_unique_all 
    WHERE (tea_app_id = 268411) AND (last_active_date >= '2022-08-06')
) AS ut ON et.hash_uid = ut.hash_uid
GLOBAL ANY LEFT JOIN 
    SELECT 
        device_id, 
        hash_did
    FROM devices_all 
    WHERE (tea_app_id = 268411) AND (last_active_date >= '2022-08-06')
) AS dt ON et.device_id = dt.device_id
WHERE (tea_app_id = 268411) AND (event = 'app_launch') AND (event_date = '2022-08-06')
LIMIT 10
Stage执行模型基本过程(可能的):
读取 tob_apps_all 数据,按照 join key(hash_uid)进行 shuffle,数据分发到每个节点。这是一个Stage。读取 users_unique_all 数据,按照 join key(hash_uid)进行 shuffle,数据分发到每个节点。这是一个 Stage。上述两个表的数据,在每个节点上的数据进行本地 JOIN,然后再按照 join key(device_id) 进行 shuffle。这是一个 Stage。读取 devices_all 数据,按照 join key(device_id)进行 shuffle,这是一个Stage。第3步、第4步的数据,相同 join key(device_id) 的数据都在同一个节点上,然后进行本地JOIN,这是一个 Stage。汇总数据,返回 limit 10 的数据。这是一个 Stage。
统计效果如下:
查询优化器
有了上面的 stage 的执行模型,可以灵活调整 SQL 的执行顺序,字节跳动 Clickhouse 团队自研了查询优化器,根据优化规则(基于规则和代价预估)对 SQL 的执行计划进行转换,一个执行计划经过优化规则后会变成另外一个执行计划,能够准确的选择出一条效率最高的执行路径,然后构建 Stage 的 DAG 图,大幅度降低查询时间。
下图描述了整个查询的执行流程,从 SQL parse 到执行期间所有内容全部进行了重新实现(其中紫色模块),构建了一套完整的且规范的查询优化器。
还是上面的三表 JOIN 的例子,可能的一个执行过程是:
查询优化器发现 users_unique_all 表与 tob_apps_all 表的分 shard 规则一样(基于用户 ID ),所以就不会先对表按 join key 进行 shuffle,users_unique 与 tob_apps 直接基于本地表 JOIN,然后再按照 join key(device_id)进行 shuffle。这是一个 Stage。查询优化器根据规则或者代价预估决定设备表 devices_all 是需要 broadcast join 还是 shuffle join。
如果 broadcast join:在一个节点查到全部的 device 数据,然后分发到其他节点。这是一个 Stage。如果 shuffle join:在每个节点对 device 数据按照 join key(device_id) 进行 shuffle。这是一个 Stage。汇总数据,返回 limit 10 的数据。这是一个 Stage。
效果:
可以看到,查询优化器能优化典型的复杂的 SQL 的执行效率,缩短执行时间。
4. 总结
ClickHouse 最为擅长的领域是一个大宽表来进行查询,多表 JOIN 时Clickhouse 性能表现不佳。作为业内领先的用户分析与运营平台,火山引擎增长分析 DataFinder 基于海量数据做到了复杂指标能够秒级查询。本文介绍了我们是如何优化 Clickhouse JOIN 查询的。
主要有以下几个方面:
减少参与 JOIN 的表以及数据量。优先使用本地 JOIN,避免分布式 JOIN 带来的性能损耗。优化本地 JOIN,优先使用内存进行 JOIN。优化分布式 JOIN 的执行逻辑,依托于字节跳动对 ClickHouse 的深度定制化。
5. 关于我们
火山引擎增长分析 DataFinder
一站式用户分析与运营平台,为企业提供数字化消费者行为分析洞见,优化数字化触点、用户体验,支撑精细化用户运营,发现业务的关键增长点,提升企业效益。点击阅读原文立即体验产品!
欢迎加入字节跳动数据平台官方群,进行数据技术交流、获取更多内容干货
字节跳动技术团队
关注
关注
点赞
收藏
评论
火山引擎在行为分析场景下的 ClickHouse JOIN 优化
动手点关注 干货不迷路 ????1. 背景火山引擎增长分析 DataFinder 基于 ClickHouse 来进行行为日志的分析,ClickHouse 的主要版本是基于社区版改进开发的字节内部版本。主要的表结构:事件表:存储用户行为数据,以用户 ID分 shard 存储。--列出了主要的字段信息CREATETABLEtob_apps_all(`tea_app_id`...
复制链接
扫一扫
参与评论
您还未登录,请先
登录
后发表或查看评论
博客
字节跳动一站式数据治理思考及实践
12-14
202
动手点关注干货不迷路导读:今天的分享主要分四个部分:机遇与挑战、数据治理思路、技术架构演进以及未来展望1. 机遇与挑战数据治理工作有很多挑战,最主要的一点是落地比较困难。首先,治理工作中与业务有一定的矛盾。第二,治理涉及的组织和管理难度大。第三,规范“人”的动作难度大,治理过程中,需要依靠人来推进和执行,人员能力参差不起,组织文化、目标也存在不对齐的情况。第四,缺乏适配性强的产品工具。因为治理工作...
博客
火山引擎 RTC 助力抖音百万并发“云侃球”
12-07
623
动手点关注干货不迷路1. 背景及技术挑战从电视看直播到手机电脑看直播,直播技术的发展让观众可以随时、随地观看自己喜欢的比赛,并且在看比赛时通过发送表情、发文字进行互动。但表情、文字承载的信息量较小、沟通效率低,我们无法像线下一起看比赛那样和好友边看边聊、一起为精彩的比赛呐喊,观赛体验大打折扣。为了让观众获得更好的观赛体验,抖音在 2022 世界杯比赛直播中推出了“边看边聊”的玩法:每个观众都可以邀...
博客
字节跳动数据中台的 Data Catalog 系统搜索实践
11-21
777
动手点关注干货不迷路1. 背景Data Catalog 能够帮助大公司更好地梳理和管理自己的资产,是 Data-drvien 公司的重要平台。一个通用的 Data Catalog 平台通常包含元数据管理,搜索,血缘,标签,术语等功能。其中,搜索是 Data Catalog 的入口功能,承担着让用户“找到数”的主要能力。在字节跳动数据中台的 Data Catalog 系统中,每天有 70% 以上的用...
博客
火山引擎 RTC 视频性能降级策略解析
11-16
445
动手点关注干货不迷路1. 背景随着 RTC 使用场景的不断复杂化,新特性不断增多,同时用户对清晰度提升的诉求也越来越强烈,这些都对客户端机器性能提出了越来越高的要求 (越来越高的分辨率,越来越复杂的编码器等)。但机器性能差异千差万别,同时用户的操作也不可预知,高级特性的使用和机器性能的矛盾客观存在。当用户机器负载过高时,我们需要适当降级视频特性来减轻系统复杂性,确保重要功能正常使用,提升用户体验...
博客
火山引擎工具技术分享:用 AI 完成数据挖掘,零门槛完成 SQL 撰写
11-14
413
动手点关注干货不迷路在使用 BI 工具的时候,经常遇到的问题是:“不会 SQL 怎么生产加工数据、不会算法可不可以做挖掘分析?”而专业算法团队在做数据挖掘时,数据分析及可视化也会呈现相对割裂的现象。流程化完成算法建模和数据分析工作,也是一个提效的好办法。同时,对于专业数仓团队来说,相同主题的数据内容面临“重复建设,使用和管理时相对分散”的问题——究竟有没有办法在一个任务里同时生产,同主题不同内容的...
博客
大规模分布式链路分析计算在字节跳动的实践
11-07
1024
动手点关注干货不迷路1. 综述微服务架构的快速发展使得分布式链路追踪系统成为观测体系中越来越重要的组件。字节跳动的分布式链路追踪系统经历了数年的发展后,已覆盖了字节的绝大部分在线业务,完成了对数万微服务和数百万微服务实例的在线链路追踪。在经典的指标观测分析和单请求链路追踪的基础上,如何从浩瀚如海的分布式链路数据中进一步挖掘出更高层次的信息,为业务的架构优化、服务治理、成本优化等场景提供更高效的数据...
博客
深度解析字节跳动开源数据集成引擎 BitSail
11-01
975
动手点关注干货不迷路1. 导读BitSail 是字节跳动开源数据集成引擎,支持多种异构数据源间的数据同步,并提供离线、实时、全量、增量场景下全域数据集成解决方案,目前支撑了字节内部和火山引擎多个客户的数据集成需求。经过字节跳动各大业务线海量数据的考验,在性能、稳定性上得到较好验证。10 月 26 日,字节跳动宣布 BitSail 项目正式在 GitHub 开源,为更多的企业和开发者带来便利,降低数...
博客
一文了解 DataLeap 中的 Notebook
10-27
1856
动手点关注干货不迷路一、概述Notebook 是一种支持 REPL 模式的开发环境。所谓「REPL」,即「读取-求值-输出」循环:输入一段代码,立刻得到相应的结果,并继续等待下一次输入。它通常使得探索性的开发和调试更加便捷。在 Notebook 环境,你可以交互式地在其中编写你的代码、运行代码、查看输出、可视化数据并查看结果,使用起来非常灵活。在数据开发领域,Notebook 广泛应用于数据清理和...
博客
火山引擎 RTC 全球化架构设计
10-24
1072
动手点关注干货不迷路1. 为什么 RTC 要做全球化RTC(Real Time Communication)是音视频基础设施,它已经融入了大家生活的方方面面:工作中,我们组织视频会议,即使团队成员身处异国,也能保证项目推进;休息时,我们打开抖音,看主播直播连麦;来一局游戏时,我们打开小队语音,大杀四方;学习时,我们相聚线上互动课堂,知识传播不再受距离的桎梏。RTC 拉近了大家的距离,丰富了大家的生...
博客
Spark AQE SkewedJoin 在字节跳动的实践和优化
10-12
1768
动手点关注干货不迷路1. 概述本文将首先介绍 Spark AQE SkewedJoin 的基本原理以及字节跳动在使用 AQE SkewedJoin 的实践中遇到的一些问题;其次介绍针对遇到的问题所做的相关优化和功能增强,以及相关优化在字节跳动的收益;此外,我们还将分享 SkewedJoin 的使用经验。2. 背景首先对 Spark AQE SkewedJoin 做一个简单的介绍。Spark Ada...
博客
深入理解 Android Studio Sync 流程
10-10
1958
动手点关注干货不迷路1. 初识 Sync我们一般会把 Sync 理解为 Android Studio 的准备阶段,包括解析工程配置信息、下载远程依赖到本地、更新代码索引等准备工作,当修改 gradle build 文件后,需要重新 Sync 将 Gradle 构建配置信息同步到 IDE,进而使 IDE 的功能及时应用新的构建配置,这些功能包括项目的 Gradle Task 列表展示、依赖信息展示等...
博客
火山引擎 RTC 自研音频编码器 NICO 实践之路
09-30
1683
动手点关注干货不迷路1. 前言随着互联网技术的不断发展,越来越多的人开始尝试使用或者依赖实时音视频产品解决团队沟通与协作问题。在通话过程中,我们时常会遇到因为网络波动(如拥塞、丢包、延时和抖动等)而导致的音频卡顿、掉字或者杂音等问题,影响工作效率。为解决此类音频弱网问题,业界一般采用前向纠错(Forward Error Correction,FEC)或者重传等网络策略优化方法,但这些方法存在冗余率...
博客
prompt 综述
09-28
1365
动手点关注干货不迷路1. 概述1.1 基本概念用一句话概括模板学习,即将原本的输入文本填入一个带有输入和输出槽位的模板,然后利用预训练语言模型预测整个句子,最终可以利用这个完整的句子导出最终需要的答案。模板学习最吸引人的关键在于其通过已有的预训练模型,定义合适的模板就能完成 few-shot 或者 zero-shot 任务,这样可以使得语言模型可以在预训练阶段利用尽可能多的信息进行训练,后续也能最...
博客
初探自然语言预训练技术演进之路
09-27
879
动手点关注干货不迷路人工智能的三个层次:运算职能:数据的存储和计算能力,机器远胜于人类。感知职能:视觉、听觉等能力,机器在语音识别、图像识别领域已经比肩人类。认知智能:自然语言处理、常识建模与推理等任务,机器还有很长的路要走。自然语言处理属于认知智能范畴,由于自然语言具有抽象性、组合性、歧义性、知识性、演化性等特点,为机器处理带来了极大的挑战,有人将自然语言处理称为人工智能皇冠上的明珠。近些年来,...
博客
Redis 持久化策略浅析
09-26
1298
动手点关注干货不迷路Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的内存高速缓存数据存储服务。使用 ANSI C 语言编写,支持网络、可基于内存亦可持久化的日志型、Key-Value 数据存储,并提供多种语言的 API。▶ 简介Redis 是内存数据库,数据都是存储在内存中,为了避免进程退出导致数据的永久丢失,需要定期将 Redis 中的数据以某种形式...
博客
Babel 插件:30分钟从入门到实战
09-16
1515
动手点关注 干货不迷路 ????Babel 是一个 source to source(源码到源码)的 JavaScript 编译器,简单来说,你为 Babel 提供一些 JavaScript 代码,Babel 可以更改这些代码,然后返回给你新生成的代码。Babel 主要用于将 ECMAScript 2015+ 代码转换为能够向后兼容的 JavaScript 版本。Babel 使用插件系统进行代码转换,因...
博客
HiveServer2 内存泄漏问题定位与优化方案
09-09
1842
动手点关注 干货不迷路 ????前言HiveServer2 属于 Hive 组件的一个服务,主要提供 Hive 访问接口,例如可通过 JDBC 的方式提交 Hive 作业,HiveServer2 基于 Java 开发,整个服务运行过程中,内存的管理回收均由 JVM 进行控制。在 JVM 语言中的内存泄漏与 C/C++ 语言的内存泄漏会有些差异,JVM 的内存泄漏更多的是业务代码逻辑错误引起大量对象引用被...
博客
飞书 Android 升级 JDK 11 引发的 CI 构建性能问题
09-02
929
动手点关注干货不迷路????一、摘要本文从飞书 Android 升级 JDK 11 意外引发的 CI 构建性能劣化谈起,结合高版本 JDK 在 Docker 容器和 GC 方面的新特性,深挖 JVM 和 Gradle 的源码实现,抽丝剥茧地介绍了分析过程和修复方法,供其他升级 JDK 的团队参考。二、背景最近飞书适配 Android 12 时把 targetSdkVersion 和 compileSd...
博客
春节活动 - 高峰值奖励发放技术方案
08-30
1168
动手点关注 干货不迷路 ????1. 背景2022年春节活动在8款字节系 APP 上线,包含了红包雨、集年味卡和烟火大会等诸多玩法。红包雨、集卡开奖和烟火大会都存在高峰值突发流量。其中,红包雨活动会在10分钟内给几千万甚至上亿用户发放上亿现金奖励,且大多数请求集中在前3分钟。在项目启动时,红包雨活动作为最大的流量来源,预估的发红包峰值流量有180万 QPS 。为了保证用户体验、活动效果和资金安全,红包雨...
博客
抖音平台多产物代码隔离技术的实践与探索
08-26
1551
动手点关注 干货不迷路 ????前言介绍在软件架构领域,框架的功能类似于基础设施服务,是为实现某个业界标准而形成的组件规范。简单理解,框架就是制定一套规范或者规则,开发同学在该规范或者规则下工作。本文通过剖析框架实体 ServiceKit/Adapter ,来窥探其底层结构和架构设计。背景描述随着抖音业务的发展,为保障整体工程演进和迭代计划的高效运行,体系化建设已加速提上日程,Codebase(可通称为...
“相关推荐”对你有帮助么?
非常没帮助
没帮助
一般
有帮助
非常有帮助
提交
字节跳动技术团队
CSDN认证博客专家
CSDN认证企业博客
238
原创
9690
周排名
1719
总排名
128万+
访问
等级
8466
积分
5913
粉丝
656
获赞
369
评论
2165
收藏
私信
关注
热门文章
抖音品质建设 - iOS启动优化之原理篇
38182
字节跳动自研万亿级图数据库 & 图计算实践
31420
字节跳动技术团队年度 TOP10 技术干货,陪你度过不平凡的 2020
27557
字节跳动自研线上引流回放系统的架构演进
26426
字节跳动开源云原生机器学习平台 Klever
24539
最新评论
浅谈Linux设备虚拟化技术的演进之路
Bill_Xiang:
vdpa将virtio带入了容器领域,容器是说只能用内核驱动的网络设备,没有vdpa之前virtio应该是说只能虚拟机用,有了vdpa之后容器也能用virtio硬件设备了,然后vduse又进一步可以给容器提供软件的virtio设备,总的来说还是用在容器的场景里,可以这么理解吧
Android 系统 Bar 沉浸式完美兼容方案
huaqiangsina:
鸿蒙无效。
字节跳动智能创作团队多篇论文入选 CVPR 2022
小菜鸡加油:
Dressing in the Wild by Watching Dance Videos 这一篇没有代码吗
抖音Android无障碍开发知识总结
qiixiao:
所以,抖音app是和Mac一样,支持按键操作吗?
西瓜视频 iOS Voice Over 无障碍适配实践
LTOVE-CODE:
多音字怎么处理的
您愿意向朋友推荐“博客详情页”吗?
强烈不推荐
不推荐
一般般
推荐
强烈推荐
提交
最新文章
字节跳动一站式数据治理思考及实践
火山引擎 RTC 助力抖音百万并发“云侃球”
字节跳动数据中台的 Data Catalog 系统搜索实践
2022
12月
2篇
11月
5篇
10月
4篇
09月
8篇
08月
11篇
07月
14篇
06月
21篇
05月
17篇
04月
11篇
03月
6篇
02月
8篇
01月
8篇
2021年58篇
2020年47篇
2019年12篇
2017年6篇
目录
目录
最新文章
字节跳动一站式数据治理思考及实践
火山引擎 RTC 助力抖音百万并发“云侃球”
字节跳动数据中台的 Data Catalog 系统搜索实践
2022
12月
2篇
11月
5篇
10月
4篇
09月
8篇
08月
11篇
07月
14篇
06月
21篇
05月
17篇
04月
11篇
03月
6篇
02月
8篇
01月
8篇
2021年58篇
2020年47篇
2019年12篇
2017年6篇
目录
评论
被折叠的 条评论
为什么被折叠?
到【灌水乐园】发言
查看更多评论
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额
抵扣说明:
1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。 2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。
余额充值