<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
  xmlns:atom="http://www.w3.org/2005/Atom"
  xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>开源大数据驿站</title>
    <link>https://blog.kpretty.tech/</link>
    
    <image>
      <url>https://blog.kpretty.tech/favicon.ico</url>
      <title>开源大数据驿站</title>
      <link>https://blog.kpretty.tech/</link>
    </image>
    
    <atom:link href="https://blog.kpretty.tech/rss.xml" rel="self" type="application/rss+xml"/>
    
    <description>让大数据知识如快递驿站般流转高效，触手可及</description>
    <pubDate>Wed, 25 Feb 2026 03:07:47 GMT</pubDate>
    <generator>http://hexo.io/</generator>
    
    <item>
      <title>GLM-4.5 &amp; Dify：零成本构建 PostAI</title>
      <link>https://blog.kpretty.tech/p/bc3c81e2.html</link>
      <guid>https://blog.kpretty.tech/p/bc3c81e2.html</guid>
      <pubDate>Sat, 10 Jan 2026 17:13:57 GMT</pubDate>
      
        
        
          
          
      <description>&lt;p&gt;PostAI 是博客网站与 AI 结合的产物，为网站提供智能客服与搜索增强功能，同时对于首次访问网站的用户可以依靠 PostAI 快速了解网站主题与热门文章。因此 PostAI 的角色是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;智能客服&lt;/li&gt;
&lt;li&gt;智能搜索&lt;/li&gt;
&lt;li&gt;智能摘要&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://oss.kpretty.tech/archives/ai/post-ai/result_display.webp&quot; alt=&quot;结果展示&quot;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如果您是在主站中刷到这篇文章，任意地方鼠标右键点击「智能管家」即可体验，其它渠道可以先访问：&lt;a href=&quot;https://blog.kpretty.tech/&quot;&gt;https://blog.kpretty.tech/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&quot;一、设计思路&quot;&gt;&lt;a href=&quot;#一、设计思路&quot; class=&quot;headerlink&quot; title=&quot;一、设计思路&quot;&gt;&lt;/a&gt;一、设计思路&lt;/h1&gt;&lt;p&gt;围绕「客服」、「搜索」和「摘要」容易想到的是 AI + 知识库，将博客与文章相关的数据定时同步到知识库。例如：dify 与扣子的知识库都提供基于 sitemap 的抓取工具，但是因为知识库依赖召回策略，当用户想要了解指定文章内容时是期望将整篇文章内容都返回给 AI，而知识库往往只能返回片段或者召回到其它片段。总体来说知识库在内容完整性与时效性不能很好的适配 PostAI 场景&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;知识库也可以不切分，但整体来说比较黑盒不自由。同时知识库也需要定期维护成本过高&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;一种轻量级的设计思路便是：假如可以提供博客元数据查询工具以及指定文章链接获取文章内容工具，当用户咨询 AI 关于博客的相关问题时首先调用元数据查询工具，让 AI 自主判断（或小小辅助一下）仅有的元数据是否可以回答用户的问题，如果不可以则再调用查询文章内容工具进行补充。它的好处如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;实时，接口可以实时获取到最新的博客数据&lt;/li&gt;
&lt;li&gt;轻量，无需持久化任何数据&lt;/li&gt;
&lt;li&gt;拓展，后续可以增加工具扩展 PostAI 能力&lt;/li&gt;
&lt;/ol&gt;
&lt;h1</description>
          
        
      
      
      
      
      <category domain="https://blog.kpretty.tech/categories/AI/">AI</category>
      
      
      <category domain="https://blog.kpretty.tech/tags/ai/">ai</category>
      
      <category domain="https://blog.kpretty.tech/tags/dify/">dify</category>
      
      <category domain="https://blog.kpretty.tech/tags/llm/">llm</category>
      
      
      <comments>https://blog.kpretty.tech/p/bc3c81e2.html#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>JSON数据处理新思路：深入SparkSQL复杂类型</title>
      <link>https://blog.kpretty.tech/p/27dc26d9.html</link>
      <guid>https://blog.kpretty.tech/p/27dc26d9.html</guid>
      <pubDate>Tue, 06 Jan 2026 10:13:57 GMT</pubDate>
      
        
        
          
          
      <description>&lt;p&gt;&lt;strong&gt;在实际的数据处理工作中，处理多层嵌套、结构不规则的JSON数据，是一个常见的挑战。&lt;/strong&gt;&lt;br&gt;传统方法通常依赖一系列字符串解析函数（如&lt;code&gt;get_json_object&lt;/code&gt;）与行展开操作（&lt;code&gt;explode&lt;/code&gt;）。这种方式不仅导致SQL语句冗长复杂，难以维护，而且在处理深层嵌套或复杂数组时，性能开销显著，逻辑也容易出错。&lt;br&gt;面对这一问题，SparkSQL提供了一套更为优雅和高效的解决方案：&lt;strong&gt;复杂数据类型（Struct, Array, Map）&lt;/strong&gt;。这些类型允许我们将完整的JSON结构直接加载为表中的一列，并在此结构之上，使用扩展的SQL语法进行精确的查询和操作。这意味着，无需预先进行繁琐的扁平化处理，我们就能直接访问嵌套字段、遍历数组元素或映射键值对，从而极大地简化了代码逻辑，并提升了处理效率。&lt;br&gt;本文不仅教会你如何解析任意复杂结构的 JSON 数据，同时还会告诉你如何封装一个 JSON 数据。&lt;/p&gt;
&lt;h1 id=&quot;一、复杂数据类型及其配套函数&quot;&gt;&lt;a href=&quot;#一、复杂数据类型及其配套函数&quot; class=&quot;headerlink&quot; title=&quot;一、复杂数据类型及其配套函数&quot;&gt;&lt;/a&gt;一、复杂数据类型及其配套函数&lt;/h1&gt;&lt;p&gt;在传统的关系型数据库与SQL中，数据模型通常被约束在“第一范式”之内，即所有数据都是原子性的，表中的每一列都是不可再分的基本数据类型。然而，现实世界中的数据，尤其是来自现代应用日志、API接口和传感器数据的JSON格式，往往是多层嵌套、结构复杂的。&lt;br&gt;为了在保持SQL关系模型强大查询能力的同时，原生地处理这种半结构化数据，SparkSQL引入了三种核心的&lt;strong&gt;复杂数据类型&lt;/strong&gt;：&lt;code&gt;STRUCT&lt;/code&gt;、&lt;code&gt;ARRAY&lt;/code&gt;和&lt;code&gt;MAP&lt;/code&gt;。这三种类型允许我们将一个具有内部结构的数据块，作为表中的一列来处理，从而在数据建模和查询上提供了极大的灵活性。&lt;/p&gt;
&lt;h2 id=&quot;1-1-数据类型&quot;&gt;&lt;a href=&quot;#1-1-数据类型&quot; class=&quot;headerlink&quot; title=&quot;1.1 数据类型&quot;&gt;&lt;/a&gt;1.1 数据类型&lt;/h2&gt;&lt;h3</description>
          
        
      
      
      
      
      <category domain="https://blog.kpretty.tech/categories/%E5%A4%A7%E6%95%B0%E6%8D%AE/">大数据</category>
      
      
      <category domain="https://blog.kpretty.tech/tags/spark/">spark</category>
      
      <category domain="https://blog.kpretty.tech/tags/json/">json</category>
      
      
      <comments>https://blog.kpretty.tech/p/27dc26d9.html#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>别再让 Excel 毁了你下班前的灵感</title>
      <link>https://blog.kpretty.tech/p/c13c7475.html</link>
      <guid>https://blog.kpretty.tech/p/c13c7475.html</guid>
      <pubDate>Wed, 03 Sep 2025 10:05:06 GMT</pubDate>
      
        
        
          
          
      <description>&lt;blockquote&gt;
&lt;p&gt;写给所有把数据仓库当“一次加工”，把本地电脑当“二次战场”的数据人&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;先来三个灵魂拷问&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;你上一次把 ADS 表导出 Excel 做探查，是不是卡到风扇起飞?&lt;/li&gt;
&lt;li&gt;你上一次 vlookup 三张百万行 CSV，是不是蓝屏死机?&lt;/li&gt;
&lt;li&gt;你上一次把 Excel 粘给老板，是不是被问“能不能换个格式，我要透视”?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果你都点头，那恭喜你——&lt;strong&gt;你已经在做“二次分析”了&lt;/strong&gt;&lt;br&gt;而二次分析，正是&lt;strong&gt;DuckDB&lt;/strong&gt;在今天依旧值得被数据人放进工具箱的最大理由。&lt;/p&gt;
&lt;h1 id=&quot;一、闲谈&quot;&gt;&lt;a href=&quot;#一、闲谈&quot; class=&quot;headerlink&quot; title=&quot;一、闲谈&quot;&gt;&lt;/a&gt;一、闲谈&lt;/h1&gt;&lt;h2 id=&quot;1-1-什么是二次分析&quot;&gt;&lt;a href=&quot;#1-1-什么是二次分析&quot; class=&quot;headerlink&quot; title=&quot;1.1 什么是二次分析&quot;&gt;&lt;/a&gt;1.1 什么是二次分析&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;一次加工&lt;/th&gt;
&lt;th&gt;二次分析&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;位置&lt;/td&gt;
&lt;td&gt;数仓&amp;#x2F;Hadoop&amp;#x2F;Spark&lt;/td&gt;
&lt;td&gt;本地电脑&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;产出&lt;/td&gt;
&lt;td&gt;dwd&amp;#x2F;dws&amp;#x2F;ads</description>
          
        
      
      
      
      
      <category domain="https://blog.kpretty.tech/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/">数据库</category>
      
      
      <category domain="https://blog.kpretty.tech/tags/skill/">skill</category>
      
      <category domain="https://blog.kpretty.tech/tags/analyze/">analyze</category>
      
      <category domain="https://blog.kpretty.tech/tags/duckdb/">duckdb</category>
      
      
      <comments>https://blog.kpretty.tech/p/c13c7475.html#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>CoalescingMergeTree：列级合并，一行成景</title>
      <link>https://blog.kpretty.tech/p/85793ab4.html</link>
      <guid>https://blog.kpretty.tech/p/85793ab4.html</guid>
      <pubDate>Wed, 27 Aug 2025 09:10:06 GMT</pubDate>
      
        
        
          
          
      <description>&lt;p&gt;CoalescingMergeTree 引擎通过&lt;strong&gt;追加写&lt;/strong&gt;的方式，为 ClickHouse 带来了真正的&lt;strong&gt;列级更新&lt;/strong&gt;能力。作为 MergeTree 家族的新成员，它能够在后台合并时，把稀疏的局部记录逐步聚合成完整行，非常适合以下场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;需要高效保留每个实体的&lt;strong&gt;最完整版本&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;可接受&lt;strong&gt;后台合并时才落盘整合&lt;/strong&gt;的延迟&lt;/li&gt;
&lt;li&gt;只想&lt;strong&gt;填补缺失字段&lt;/strong&gt;，而非像 ReplacingMergeTree 那样整行覆盖&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;CoalescingMergeTree 首发于 25.6 版本，25.7.2.54 已具备完整更新能力。详情查看&lt;a href=&quot;https://github.com/ClickHouse/ClickHouse/issues/84116&quot;&gt;issue #84116&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&quot;一、实现原理&quot;&gt;&lt;a href=&quot;#一、实现原理&quot; class=&quot;headerlink&quot; title=&quot;一、实现原理&quot;&gt;&lt;/a&gt;一、实现原理&lt;/h1&gt;&lt;h2 id=&quot;1-1-八股文版&quot;&gt;&lt;a href=&quot;#1-1-八股文版&quot; class=&quot;headerlink&quot; title=&quot;1.1 八股文版&quot;&gt;&lt;/a&gt;1.1 八股文版&lt;/h2&gt;&lt;p&gt;与其它 MergeTree 引擎一样，需要先通过 &lt;code&gt;ORDER BY&lt;/code&gt; 声明排序键（主键）。CoalescingMergeTree 会把相同排序键的多条记录做合并，规则：&lt;strong&gt;每列保留最新的非 NULL 值&lt;/strong&gt;，最终在磁盘上得到一行“完整”数据。&lt;br&gt;&lt;img src=&quot;https://oss.kpretty.tech/archives/clickhouse/coalescingmergetree/merge.webp&quot; alt=&quot;merge&quot;&gt;&lt;br&gt;其中 1- 4 为数据 insert 过程，对于同一个 vin 每次插入局部数据&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;初始化 vin</description>
          
        
      
      
      
      
      <category domain="https://blog.kpretty.tech/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/">数据库</category>
      
      
      <category domain="https://blog.kpretty.tech/tags/clickhouse/">clickhouse</category>
      
      <category domain="https://blog.kpretty.tech/tags/skill/">skill</category>
      
      
      <comments>https://blog.kpretty.tech/p/85793ab4.html#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>可刷新物化视图</title>
      <link>https://blog.kpretty.tech/p/3cf62ee5.html</link>
      <guid>https://blog.kpretty.tech/p/3cf62ee5.html</guid>
      <pubDate>Mon, 07 Jul 2025 08:45:06 GMT</pubDate>
      
        
        
          
          
      <description>&lt;p&gt;可刷新物化视图 (refreshable materialized view) 是 ClickHouse 一种新的物化视图解决方案，并在&lt;strong&gt;24.10&lt;/strong&gt;版本中标记为&lt;strong&gt;生产可用&lt;/strong&gt;。主要用于&lt;strong&gt;解决增量物化视图不适用的场景&lt;/strong&gt;。&lt;/p&gt;
&lt;h1 id=&quot;一、增量物化视图&quot;&gt;&lt;a href=&quot;#一、增量物化视图&quot; class=&quot;headerlink&quot; title=&quot;一、增量物化视图&quot;&gt;&lt;/a&gt;一、增量物化视图&lt;/h1&gt;&lt;p&gt;增量物化视图是 ClickHouse 中常见的物化视图。下面我们来介绍它的更新时机以及不适用的场景，以引出可刷新物化视图推出的背景。&lt;/p&gt;
&lt;h2 id=&quot;1-更新时机&quot;&gt;&lt;a href=&quot;#1-更新时机&quot; class=&quot;headerlink&quot; title=&quot;1.更新时机&quot;&gt;&lt;/a&gt;1.更新时机&lt;/h2&gt;&lt;p&gt;从本质上说，增量物化视图是主表&lt;code&gt;insert&lt;/code&gt;事件的&lt;strong&gt;触发器&lt;/strong&gt;。当主表有数据插入时，会将本次插入的数据应用物化视图的建表 SQL，并写入物化视图或其 to 表（后面全部用 to 表解释）。&lt;br&gt;&lt;img src=&quot;https://oss.kpretty.tech/archives/clickhouse/refreshable_materialized/principle.webp&quot; alt=&quot;principle&quot;&gt;&lt;br&gt;上述是单表增量物化视图更新时机极其数据扭转。&lt;/p&gt;
&lt;p&gt;对于多表 join 的增量物化视图，其更新时机略有区别。也正是因为其独特的机制，导致增量物化视图无法应用于所有多表场景。下面构建一个多表 join 的增量物化视图场景：&lt;/p&gt;
&lt;figure class=&quot;highlight sql&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;-- 数据源表 1&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;create table&lt;/span&gt; tbl1(  &lt;/span&gt;&lt;br&gt;&lt;span</description>
          
        
      
      
      
      
      <category domain="https://blog.kpretty.tech/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/">数据库</category>
      
      
      <category domain="https://blog.kpretty.tech/tags/clickhouse/">clickhouse</category>
      
      <category domain="https://blog.kpretty.tech/tags/skill/">skill</category>
      
      
      <comments>https://blog.kpretty.tech/p/3cf62ee5.html#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>辛普森悖论的量化根因</title>
      <link>https://blog.kpretty.tech/p/99aef10e.html</link>
      <guid>https://blog.kpretty.tech/p/99aef10e.html</guid>
      <pubDate>Sat, 28 Jun 2025 14:57:45 GMT</pubDate>
      
        
        
          
          
      <description>&lt;p&gt;&lt;strong&gt;辛普森悖论&lt;/strong&gt;（simpson’s paradox），是概率和统计中的一种现象，其中趋势出现在几组数据中，但当这些组被合并后趋势&lt;strong&gt;消失或反转&lt;/strong&gt;。这个结果在社会科学和医学科学统计中经常遇到，当频率数据被不恰当地给出因果解释时尤其成问题。当干扰变量和因果关系在统计建模中得到适当处理时，这个悖论就可以得到解决。 辛普森悖论已被用来说明统计误用可能产生的误导性结果。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://oss.kpretty.tech/archives/other/simpsons_paradox/simpsons_paradox_plan.gif&quot; alt=&quot;辛普森悖论解释&quot;&gt;&lt;/p&gt;
&lt;p&gt;关于辛普森悖论的论述推荐知乎上两篇高赞回复&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/348967975&quot;&gt;关于辛普森悖论的深度解析&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/430437810&quot;&gt;真实的谎言——辛普森悖论面面观&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;而本文的主题是当博主在工作中遇到辛普森悖论时如何去量化根因&lt;del&gt;(打脸业务我的数据没有出问题)&lt;/del&gt;&lt;/p&gt;
&lt;h1 id=&quot;一、背景&quot;&gt;&lt;a href=&quot;#一、背景&quot; class=&quot;headerlink&quot;</description>
          
        
      
      
      
      
      <category domain="https://blog.kpretty.tech/categories/%E5%85%B6%E5%AE%83/">其它</category>
      
      
      <category domain="https://blog.kpretty.tech/tags/skill/">skill</category>
      
      <category domain="https://blog.kpretty.tech/tags/idea/">idea</category>
      
      
      <comments>https://blog.kpretty.tech/p/99aef10e.html#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>基于 metabase + clickhouse 的流量分析</title>
      <link>https://blog.kpretty.tech/p/3a240ecc.html</link>
      <guid>https://blog.kpretty.tech/p/3a240ecc.html</guid>
      <pubDate>Sun, 08 Jun 2025 06:41:17 GMT</pubDate>
      
        
        
          
          
      <description>&lt;h1 id=&quot;一、背景&quot;&gt;&lt;a href=&quot;#一、背景&quot; class=&quot;headerlink&quot; title=&quot;一、背景&quot;&gt;&lt;/a&gt;一、背景&lt;/h1&gt;&lt;p&gt;&lt;a href=&quot;https://blog.kpretty.tech/&quot;&gt;博客&lt;/a&gt;的访问统计是基于&lt;a href=&quot;https://v6.51.la/&quot;&gt;51la&lt;/a&gt;实现，其只会统计“真人”的访问记录会过滤掉绝大部分的全站流量，因此如果想要分析全站的流量是否存在异常则需要更底层的实现。博客的基础架构是 nginx + hexo 的静态博客页面，因此全站流量分析的思路是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;采集 nginx 的访问日志&lt;/li&gt;
&lt;li&gt;同步到分析性数据库&lt;/li&gt;
&lt;li&gt;搭建实时报表&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;结合博主的技术栈，设计出如下架构&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://oss.kpretty.tech/archives/project/traffic-analysis/infrastructure-diagram.webp&quot; alt=&quot;基础流量架构&quot;&gt;&lt;/p&gt;
&lt;h1 id=&quot;二、框架解析&quot;&gt;&lt;a href=&quot;#二、框架解析&quot; class=&quot;headerlink&quot; title=&quot;二、框架解析&quot;&gt;&lt;/a&gt;二、框架解析&lt;/h1&gt;&lt;p&gt;本节解释为什么要选择 vector + clickhouse + metabase&lt;/p&gt;
&lt;h2 id=&quot;2-1-vector&quot;&gt;&lt;a href=&quot;#2-1-vector&quot; class=&quot;headerlink&quot; title=&quot;2.1 vector&quot;&gt;&lt;/a&gt;2.1 vector&lt;/h2&gt;&lt;p&gt;vector 是一个轻量级、超快用于构建可观测数据管道的工具，这里用作日志采集的 ETL工具。相较于 flume 或 filebeat + logstash 有以下优点&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;使用 rust 编写，无 gc 运行效率极高且部署简单无需额外的环境（flume 或 ELK 都需要 jre）&lt;/li&gt;
&lt;li&gt;vector 支持 44 种 source、15 种 transform 和 59 种 sink&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;同时要考虑实际情况，博主公网服务器的配置仅为 2c4g，vector</description>
          
        
      
      
      
      
      <category domain="https://blog.kpretty.tech/categories/%E5%AE%9E%E9%AA%8C%E9%A1%B9%E7%9B%AE/">实验项目</category>
      
      
      <category domain="https://blog.kpretty.tech/tags/clickhouse/">clickhouse</category>
      
      <category domain="https://blog.kpretty.tech/tags/metabase/">metabase</category>
      
      <category domain="https://blog.kpretty.tech/tags/nginx/">nginx</category>
      
      <category domain="https://blog.kpretty.tech/tags/analysis/">analysis</category>
      
      
      <comments>https://blog.kpretty.tech/p/3a240ecc.html#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>TTL——管理 clickhouse 数据的生命周期</title>
      <link>https://blog.kpretty.tech/p/b7172a68.html</link>
      <guid>https://blog.kpretty.tech/p/b7172a68.html</guid>
      <pubDate>Fri, 30 May 2025 10:45:06 GMT</pubDate>
      
        
        
          
          
      <description>&lt;p&gt;随着时间的推移，clickhouse 中的数据逐步增长。为了查询、存储效率的提升我们可能需要计划性删除、移动或聚合历史数据。针对此类数据生命周期管理，clickhouse 提供了简单且强大的工具——TTL，该工具作用于 DDL 子句中。这篇文章将探索 TTL 以及如何使用它来解决多种数据管理任务。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;TTL 只能应用在 MergeTree 系列引擎中&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&quot;一、删除数据&quot;&gt;&lt;a href=&quot;#一、删除数据&quot; class=&quot;headerlink&quot; title=&quot;一、删除数据&quot;&gt;&lt;/a&gt;一、删除数据&lt;/h1&gt;&lt;p&gt;在一些特殊的场景中，有时存储过期的数据是没有意义的，因此需要定期执行删除操作。而 clickhouse 只需要在 DDL 中配置 TTL 就可以在后台自动完成。同时对于删除操作又可以细分为&lt;strong&gt;删除整行&lt;/strong&gt;或只&lt;strong&gt;删除指标列&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;1-1-删除整行&quot;&gt;&lt;a href=&quot;#1-1-删除整行&quot; class=&quot;headerlink&quot; title=&quot;1.1 删除整行&quot;&gt;&lt;/a&gt;1.1 删除整行&lt;/h2&gt;&lt;h3 id=&quot;1-普通删除&quot;&gt;&lt;a href=&quot;#1-普通删除&quot; class=&quot;headerlink&quot; title=&quot;1. 普通删除&quot;&gt;&lt;/a&gt;1. 普通删除&lt;/h3&gt;&lt;p&gt;假设有一张&lt;code&gt;event&lt;/code&gt;表，同时我们期望自动删除所有超过一个月的记录&lt;/p&gt;
&lt;figure class=&quot;highlight sql&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;create table&lt;/span&gt; events&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;(&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    event String,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;type&quot;&gt;time&lt;/span&gt;  DateTime,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span</description>
          
        
      
      
      
      
      <category domain="https://blog.kpretty.tech/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/">数据库</category>
      
      
      <category domain="https://blog.kpretty.tech/tags/clickhouse/">clickhouse</category>
      
      <category domain="https://blog.kpretty.tech/tags/ttl/">ttl</category>
      
      
      <comments>https://blog.kpretty.tech/p/b7172a68.html#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>ClickHouse 查询缓存</title>
      <link>https://blog.kpretty.tech/p/9498adf0.html</link>
      <guid>https://blog.kpretty.tech/p/9498adf0.html</guid>
      <pubDate>Fri, 30 May 2025 10:29:11 GMT</pubDate>
      
        
        
          
          
      <description>&lt;p&gt;为了实现最佳性能，数据库需要优化其内部数据存储和处理管道的每一步。但是数据库执行的最好的工作是根本没有完成的工作！缓存是一种特别流行的技术，它通过存储早期计算的结果或远程数据来避免不必要的工作，而访问这些数据的成本往往很高。在今天的博文中，介绍一下 ClickHouse 缓存系列的最新成员——查询缓存，在 v23.1 版本中作为实验性特性。&lt;/p&gt;
&lt;h1 id=&quot;一、缓存一致性问题&quot;&gt;&lt;a href=&quot;#一、缓存一致性问题&quot; class=&quot;headerlink&quot; title=&quot;一、缓存一致性问题&quot;&gt;&lt;/a&gt;一、缓存一致性问题&lt;/h1&gt;&lt;p&gt;在实操 clickhouse 的查询缓存前需要先了解一下缓存事务问题，查询缓存通常可以分为事务一致和事务不一致。&lt;/p&gt;
&lt;p&gt;在事务一致缓存中，如果 SELECT 查询的结果发生更改或可能发生更改，则数据库会使缓存的查询结果无效（丢弃）。在 ClickHouse 中，更改数据的操作包括在表中插入&amp;#x2F;更新&amp;#x2F;删除或折叠合并。事务一致性缓存特别适合 OLTP 数据库，例如MySQL（在v8.0之后删除了查询缓存）和 Oracle。&lt;/p&gt;
&lt;p&gt;在事务不一致缓存中，所有缓存条目都被分配了一个有效期，之后它们就会过期，并且基础数据在此期间仅发生很小的变化，那么查询结果中的轻微不准确是可以接受的，这种方法总体上更适合 OLAP 数据库。在一些应用场景中数据的变化假如很慢，数据库就只需要计算一次报告（由第一个 SELECT 查询表示）。可以直接从查询缓存提供进一步的查询。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;事务上不一致的缓存通常是由与数据库交互的客户端工具或代理包提供的&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&quot;二、查询缓存实操&quot;&gt;&lt;a href=&quot;#二、查询缓存实操&quot; class=&quot;headerlink&quot; title=&quot;二、查询缓存实操&quot;&gt;&lt;/a&gt;二、查询缓存实操&lt;/h1&gt;&lt;h2 id=&quot;2-1-前期准备&quot;&gt;&lt;a href=&quot;#2-1-前期准备&quot; class=&quot;headerlink&quot; title=&quot;2.1 前期准备&quot;&gt;&lt;/a&gt;2.1 前期准备&lt;/h2&gt;&lt;p&gt;这里使用 clickhouse 官方提供的 Anonymized Web Analytics Data，&lt;a</description>
          
        
      
      
      
      
      <category domain="https://blog.kpretty.tech/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/">数据库</category>
      
      
      <category domain="https://blog.kpretty.tech/tags/clickhouse/">clickhouse</category>
      
      <category domain="https://blog.kpretty.tech/tags/cache/">cache</category>
      
      
      <comments>https://blog.kpretty.tech/p/9498adf0.html#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>Clickhouse 的 Kafka 表引擎</title>
      <link>https://blog.kpretty.tech/p/1808cf2d.html</link>
      <guid>https://blog.kpretty.tech/p/1808cf2d.html</guid>
      <pubDate>Sat, 01 Mar 2025 03:50:29 GMT</pubDate>
      
        
        
          
          
      <description>&lt;p&gt;Kafka 是大数据领域非常流行的一款分布式消息中间件，是实时计算中必不可少的一环，同时一款 OLAP 系统能否对接 Kafka 也算是考量是否具备流批一体的衡量指标之一。ClickHouse 的 Kafka 表引擎能够直接与 Kafka 系统对接，进而订阅 Kafka 中的 Topic 并实时接受消息数据。&lt;/p&gt;
&lt;p&gt;众所周知，在消息系统中存在三层语义，它们分别是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;最多一次（at most once）：可能存在丢失数据的情况&lt;/li&gt;
&lt;li&gt;最少一次（at least once）：可能存在重复数据的情况&lt;/li&gt;
&lt;li&gt;精准一次（exactly once）：数据不多不少，最为理想的情况&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;虽然 Kafka 本身能够支持上述三层语义，但一条完整的数据链路支持的语义遵循木桶原理。ClickHouse 24.8（2024 年 9 月 3 日）前还不支持 exactly once 语义，但因为 ClickHouse 有强大的 MergeTree 系列引擎且在明确的业务场景加持下(定义业务主键)具备幂等性，当幂等性 + at least once 语义也是可以实现 exactly once。而在 ClickHouse 24.8 LST 版本中官方引入新的 Kafka 引擎这为直接实现 exactly once 语义提供了可能。&lt;/p&gt;
&lt;figure class=&quot;highlight txt&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;We also have a new experimental Kafka engine. &lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;This version makes it possible to have exactly-once processing of messages from Kafka.&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;

&lt;p&gt;本文则从零开始讲述 ClickHouse 如何与 Kafka 进行深度融合，如何在生产中优雅地使用 Kafka 表引擎同时介绍新的 Kafka 表引擎是如何实现 exactly once</description>
          
        
      
      
      
      
      <category domain="https://blog.kpretty.tech/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/">数据库</category>
      
      
      <category domain="https://blog.kpretty.tech/tags/clickhouse/">clickhouse</category>
      
      <category domain="https://blog.kpretty.tech/tags/kafka/">kafka</category>
      
      <category domain="https://blog.kpretty.tech/tags/skill/">skill</category>
      
      
      <comments>https://blog.kpretty.tech/p/1808cf2d.html#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>SparkSQL优化的行列转换</title>
      <link>https://blog.kpretty.tech/p/45108542.html</link>
      <guid>https://blog.kpretty.tech/p/45108542.html</guid>
      <pubDate>Sat, 08 Feb 2025 06:41:17 GMT</pubDate>
      
        
        
          
          
      <description>&lt;p&gt;&lt;strong&gt;行列转换&lt;/strong&gt;是数据处理与分析中的关键操作，它能够将数据的结构从行转为列，或从列转为行。这种转换不仅简化了复杂的数据展示，还提升了数据分析的效率。在业务场景中，行列转换常用于报表生成、数据透视和多维度数据分析，通过更直观的方式呈现数据，帮助管理者快速获取关键信息。此外，它还能有效减少数据冗余，优化查询性能，满足灵活多变的业务需求。无论是在财务报表、销售分析，还是市场趋势分析中，行列转换都是不可或缺的工具。&lt;/p&gt;
&lt;p&gt;本文会基于 SparkSQL 3.5.x 给出常用的行列转换方式，但本文的重点是介绍&lt;code&gt;pivot&lt;/code&gt;和&lt;code&gt;unpivot&lt;/code&gt;子句在行列转换场景的应用，其中细节、优雅程度交由开发者自己选择&lt;/p&gt;
&lt;h1 id=&quot;一、数据准备&quot;&gt;&lt;a href=&quot;#一、数据准备&quot; class=&quot;headerlink&quot; title=&quot;一、数据准备&quot;&gt;&lt;/a&gt;一、数据准备&lt;/h1&gt;&lt;p&gt;以下是城市各年GDP 数据的表结构和测试数据，用于后续演示行列转换&lt;/p&gt;
&lt;figure class=&quot;highlight sql&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;create table&lt;/span&gt; city_gdp&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;(&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    city string comment &lt;span class=&quot;string&quot;&gt;&amp;#x27;城市名&amp;#x27;&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;year&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;int&lt;/span&gt; comment &lt;span class=&quot;string&quot;&gt;&amp;#x27;年份&amp;#x27;&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    gdp  &lt;span class=&quot;keyword&quot;&gt;double&lt;/span&gt; comment &lt;span</description>
          
        
      
      
      
      
      <category domain="https://blog.kpretty.tech/categories/%E5%A4%A7%E6%95%B0%E6%8D%AE/">大数据</category>
      
      
      <category domain="https://blog.kpretty.tech/tags/skill/">skill</category>
      
      <category domain="https://blog.kpretty.tech/tags/spark/">spark</category>
      
      
      <comments>https://blog.kpretty.tech/p/45108542.html#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>Bitmap 在数仓中的应用</title>
      <link>https://blog.kpretty.tech/p/d261c272.html</link>
      <guid>https://blog.kpretty.tech/p/d261c272.html</guid>
      <pubDate>Sun, 15 Dec 2024 08:03:59 GMT</pubDate>
      
        
        
          
          
      <description>&lt;h1 id=&quot;一、背景&quot;&gt;&lt;a href=&quot;#一、背景&quot; class=&quot;headerlink&quot; title=&quot;一、背景&quot;&gt;&lt;/a&gt;一、背景&lt;/h1&gt;&lt;p&gt;在数据仓库的日常工作中，我们经常需要面对海量数据的存储和高效查询问题。尤其是，当业务对性能的要求越来越高、数据量持续增长时，传统的处理方式往往显得笨拙而低效。而这时候，&lt;strong&gt;Bitmap&lt;/strong&gt;（位图）作为一种“看似简单却威力强大”的数据结构，逐渐展现出它的价值。简单来说，Bitmap 就像是一种用“0”和“1”记录信息的小工具。它通过位的形式将数据高效地压缩存储，同时支持快速的集合运算，比如并集、交集、补集等。这些特性使得 Bitmap 在高基数去重、行为统计、快速筛选等场景中表现得尤为出色。比如，给定一个数千万级别的用户群，使用 Bitmap 技术可以在几毫秒内完成某些复杂的查询操作，这在传统方法中可能需要数十秒甚至更长时间。 Bitmap 在数据仓库中的应用非常广泛。无论是帮助优化指标计算，还是提升查询性能，它都能够为开发者解决很多头疼的问题。例如，在广告投放场景下，我们需要实时统计某一人群的曝光次数；在用户运营中，我们可能需要高效筛选出符合特定标签的用户群。这些看似复杂的任务，通过 Bitmap，往往能以优雅的方式轻松解决。 这篇文章希望以实际案例为切入点，结合 Bitmap 的原理，聊一聊它在数据仓库中的应用场景和实现方式，帮助大家更好地理解和使用这一实用工具。&lt;/p&gt;
&lt;h1 id=&quot;二、Bitmap-原理&quot;&gt;&lt;a href=&quot;#二、Bitmap-原理&quot; class=&quot;headerlink&quot; title=&quot;二、Bitmap 原理&quot;&gt;&lt;/a&gt;二、Bitmap 原理&lt;/h1&gt;&lt;h2 id=&quot;2-1-基础构成&quot;&gt;&lt;a href=&quot;#2-1-基础构成&quot; class=&quot;headerlink&quot; title=&quot;2.1 基础构成&quot;&gt;&lt;/a&gt;2.1 基础构成&lt;/h2&gt;&lt;p&gt;Bitmap 是一个连续的位数组，数组的每个位置对应一个无符号整数。例如需要存储 1、2、4、5 元素，只需要将这个数组的第 1、2、4、5 位设置为 1 其余位保持为 0 即可，即为&lt;code&gt;011011&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&quot;2-2-核心操作&quot;&gt;&lt;a href=&quot;#2-2-核心操作&quot;</description>
          
        
      
      
      
      
      <category domain="https://blog.kpretty.tech/categories/%E5%A4%A7%E6%95%B0%E6%8D%AE/">大数据</category>
      
      
      <category domain="https://blog.kpretty.tech/tags/spark/">spark</category>
      
      <category domain="https://blog.kpretty.tech/tags/bitmap/">bitmap</category>
      
      
      <comments>https://blog.kpretty.tech/p/d261c272.html#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>醉意下的真实——十年软件工程师的深夜独白</title>
      <link>https://blog.kpretty.tech/p/8738e0ed.html</link>
      <guid>https://blog.kpretty.tech/p/8738e0ed.html</guid>
      <pubDate>Fri, 15 Nov 2024 10:57:45 GMT</pubDate>
      
        
        
          
          
      <description>&lt;p&gt;作为一个在工程领域摸爬滚打十年的工程师，我今晚可能在酒精的作用下，毫无顾忌地分享一些心得体会。以下是我酒后吐真言。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;我在职业发展上取得的最大进步，是通过跳槽实现的。&lt;/li&gt;
&lt;li&gt;技术栈并不是真的那么重要，因为在我所在的领域，大约有15种基本的软件工程模式是适用的。我从事的是数据领域的工作，它与网页开发或嵌入式开发不同。但所有领域都有大约10到20个核心原则，而技术栈只是试图让这些原则更容易实现，所以不必为此烦恼。&lt;/li&gt;
&lt;li&gt;人们推崇寻找新工作是有其道理的。如果我对当前的工作感到不满意，那很可能是时候向前看了。&lt;/li&gt;
&lt;li&gt;在我曾经工作过的公司里，我结交了一些好朋友，他们将会是我一生的挚友。我并不要求我工作过的每一个地方都必须建立这样的友谊。在那些没有与同事建立友谊的地方，我也能非常快乐地工作；同样地，即使在那些我交到了好朋友的地方，有时我也可能感到不快乐。&lt;/li&gt;
&lt;li&gt;我学会了对上司坦诚，既保持真诚，又不至于过于直白，这样在工作中我能够保持自我。最糟糕的情况是什么？被解雇？那也无妨，我相信不久便能找到新的工作机会。&lt;/li&gt;
&lt;li&gt;如果我一个季度内因为值班被在凌晨两点钟叫醒超过一次，那么肯定是出了严重的问题，我要么会解决它，要么就会辞职。&lt;/li&gt;
&lt;li&gt;再倒一杯。&lt;/li&gt;
&lt;li&gt;一个优秀的管理者与一个杰出的工程师之间，有许多共通的品质。&lt;/li&gt;
&lt;li&gt;当我刚开始的时候，我对技术和编程以及计算机科学非常着迷。我现在已经不再那么狂热了。&lt;/li&gt;
&lt;li&gt;好的代码是初级工程师能够理解的。伟大的代码是计算机科学专业的大一新生都能理解的。而最好的代码是根本不需要写代码。&lt;/li&gt;
&lt;li&gt;作为工程师，编写文档的能力常被低估。真的，如果有人能教我如何编写出色的文档，我非常愿意为此付费参加培训课程。如果能保证我能够写出高质量的文档，我愿意支付高达1000美元的费用。&lt;/li&gt;
&lt;li&gt;与上述相关的，写出优秀的变更提案也是一个非常重要的技能。&lt;/li&gt;
&lt;li&gt;几乎所有的技术“圣战”（比如Vim与Emacs，Mac与Linux等）其实都是无关紧要的……但有一个例外，详情见下文。&lt;/li&gt;
&lt;li&gt;随着年龄的增长，我越来越欣赏动态语言了。该死，我说出来了。来打我啊。&lt;/li&gt;
&lt;li&gt;如果我发现自己认为我是团队</description>
          
        
      
      
      
      
      <category domain="https://blog.kpretty.tech/categories/%E5%85%B6%E5%AE%83/">其它</category>
      
      
      <category domain="https://blog.kpretty.tech/tags/translation/">translation</category>
      
      
      <comments>https://blog.kpretty.tech/p/8738e0ed.html#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>ClickHouse 多种删除操作</title>
      <link>https://blog.kpretty.tech/p/74577b67.html</link>
      <guid>https://blog.kpretty.tech/p/74577b67.html</guid>
      <pubDate>Wed, 09 Oct 2024 04:45:06 GMT</pubDate>
      
        
        
          
          
      <description>&lt;p&gt;OLAP 数据库设计的宗旨在于分析适合一次插入多次查询的业务场景，市面上成熟的 AP 数据库在更新和删除操作上支持的均不是很好，当然 clickhouse 也不例外。但是不友好不代表不支持，本文主要介绍在 clickhouse 中如何实现数据的删除，以及最新版本中 clickhouse 所做的一些技术突破。&lt;/p&gt;
&lt;h1 id=&quot;一、mutation&quot;&gt;&lt;a href=&quot;#一、mutation&quot; class=&quot;headerlink&quot; title=&quot;一、mutation&quot;&gt;&lt;/a&gt;一、mutation&lt;/h1&gt;&lt;p&gt;刚接触 clickhouse 的小伙伴或许对 mutation 就很熟悉了，mutation 查询可以看成 alter 语句的变种。虽然 mutation 能够最终实现修改和删除的需求，但不能完全用通常意义的 delete 和 update 来理解，我们需要清醒的认识到它的不同：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;mutation 是一个很重的操作，适合批量数据操作&lt;/li&gt;
&lt;li&gt;不支持事务、一旦操作立刻生效无法回滚&lt;/li&gt;
&lt;li&gt;mutation 为异步操作&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;1-1-实操&quot;&gt;&lt;a href=&quot;#1-1-实操&quot; class=&quot;headerlink&quot; title=&quot;1.1 实操&quot;&gt;&lt;/a&gt;1.1 实操&lt;/h2&gt;&lt;p&gt;创建一张表用于测试 mutation 操作&lt;/p&gt;
&lt;figure class=&quot;highlight sql&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;create table&lt;/span&gt; mutations_operate&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;(&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    UserId     UInt64,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    Score      UInt64,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    CreateTime DateTime&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;) engine &lt;span</description>
          
        
      
      
      
      
      <category domain="https://blog.kpretty.tech/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/">数据库</category>
      
      
      <category domain="https://blog.kpretty.tech/tags/clickhouse/">clickhouse</category>
      
      <category domain="https://blog.kpretty.tech/tags/skill/">skill</category>
      
      
      <comments>https://blog.kpretty.tech/p/74577b67.html#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>三年 Sparker 都不一定知道的算子内幕</title>
      <link>https://blog.kpretty.tech/p/260ad51e.html</link>
      <guid>https://blog.kpretty.tech/p/260ad51e.html</guid>
      <pubDate>Tue, 17 Sep 2024 08:03:59 GMT</pubDate>
      
        
        
          
          
      <description>&lt;h1 id=&quot;一、如何在-mapPartitions-中释放资源&quot;&gt;&lt;a href=&quot;#一、如何在-mapPartitions-中释放资源&quot; class=&quot;headerlink&quot; title=&quot;一、如何在 mapPartitions 中释放资源&quot;&gt;&lt;/a&gt;一、如何在 mapPartitions 中释放资源&lt;/h1&gt;&lt;p&gt;&lt;code&gt;mapPartitions&lt;/code&gt;是一种对每个分区进行操作的转换操作，于常用的&lt;code&gt;map&lt;/code&gt;操作类似，但它处理的是整个分区而不是单个元素。&lt;code&gt;mapPartitions&lt;/code&gt;的应用场景适合处理需要在每个分区内批量处理数据的场景，通常用于优化性能和减少计算开销。例如：减少数据库连接、网络连接等。即然涉及到资源的初始化那么必定伴随着资源的释放，这是本节讨论的重点。&lt;/p&gt;
&lt;p&gt;以和 mysql 中数据交互为例，下面是一段伪代码&lt;/p&gt;
&lt;figure class=&quot;highlight scala&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;rdd.mapPartitions(iter =&amp;gt; &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;comment&quot;&gt;// 初始化数据库连接&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;keyword&quot;&gt;lazy&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;val&lt;/span&gt; connection = initConnection(args)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;comment&quot;&gt;// 迭代数据&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;keyword&quot;&gt;val&lt;/span&gt; result = iter.map(... &lt;span class=&quot;comment&quot;&gt;/*处理逻辑会使用到 connection 对象*/&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &lt;span class=&quot;comment&quot;&gt;//</description>
          
        
      
      
      
      
      <category domain="https://blog.kpretty.tech/categories/%E5%A4%A7%E6%95%B0%E6%8D%AE/">大数据</category>
      
      
      <category domain="https://blog.kpretty.tech/tags/skill/">skill</category>
      
      <category domain="https://blog.kpretty.tech/tags/spark/">spark</category>
      
      
      <comments>https://blog.kpretty.tech/p/260ad51e.html#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>因精度丢失导致的 join 数据异常</title>
      <link>https://blog.kpretty.tech/p/c9ab2e5.html</link>
      <guid>https://blog.kpretty.tech/p/c9ab2e5.html</guid>
      <pubDate>Mon, 19 Aug 2024 00:45:06 GMT</pubDate>
      
        
        
          
          
      <description>&lt;h1 id=&quot;一、问题复现&quot;&gt;&lt;a href=&quot;#一、问题复现&quot; class=&quot;headerlink&quot; title=&quot;一、问题复现&quot;&gt;&lt;/a&gt;一、问题复现&lt;/h1&gt;&lt;p&gt;不知你是否遇到过 join 结果明显不匹配的情况，例如&lt;code&gt;on t1.join_key = t2.join_key&lt;/code&gt;中两个&lt;code&gt;join_key&lt;/code&gt;明显不相等，但 join 的结果却将其匹配在一起。今日博主在通过用户 id 关联获取用户信息时发现一个用户 id 可以在用户维表中匹配出若干条（用户维表不存在数据重复），如下：&lt;/p&gt;
&lt;figure class=&quot;highlight sql&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;-- 业务表&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;create table&lt;/span&gt; tmp_hz_perm.tmp_20240520_1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;(&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    id string&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;) stored &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; parquet;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;-- 用户维度表&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;create table&lt;/span&gt; tmp_hz_perm.tmp_20240520_2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;(&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    id   &lt;span class=&quot;type&quot;&gt;bigint&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    name string&lt;/span&gt;&lt;br&gt;&lt;span</description>
          
        
      
      
      
      
      <category domain="https://blog.kpretty.tech/categories/%E5%A4%A7%E6%95%B0%E6%8D%AE/">大数据</category>
      
      
      <category domain="https://blog.kpretty.tech/tags/hive/">hive</category>
      
      <category domain="https://blog.kpretty.tech/tags/join/">join</category>
      
      <category domain="https://blog.kpretty.tech/tags/problem/">problem</category>
      
      
      <comments>https://blog.kpretty.tech/p/c9ab2e5.html#disqus_thread</comments>
      
    </item>
    
    <item>
      <title>ClickHouse 查询缓存</title>
      <link>https://blog.kpretty.tech/p/9498adf0.html</link>
      <guid>https://blog.kpretty.tech/p/9498adf0.html</guid>
      <pubDate>Mon, 01 Apr 2024 04:45:06 GMT</pubDate>
      
        
        
          
          
      <description>&lt;p&gt;为了实现最佳性能，数据库需要优化其内部数据存储和处理管道的每一步。但是数据库执行的最好的工作是根本没有完成的工作！缓存是一种特别流行的技术，它通过存储早期计算的结果或远程数据来避免不必要的工作，而访问这些数据的成本往往很高。在今天的博文中，介绍一下 ClickHouse 缓存系列的最新成员——查询缓存，在&lt;code&gt;v23.1&lt;/code&gt;版本中作为实验性特性。&lt;/p&gt;
&lt;h1 id=&quot;一、缓存一致性问题&quot;&gt;&lt;a href=&quot;#一、缓存一致性问题&quot; class=&quot;headerlink&quot; title=&quot;一、缓存一致性问题&quot;&gt;&lt;/a&gt;一、缓存一致性问题&lt;/h1&gt;&lt;p&gt;在实操 clickhouse 的查询缓存前需要先了解一下缓存事务问题，查询缓存通常可以分为事务一致和事务不一致。&lt;br&gt;在事务一致缓存中，如果 SELECT 查询的结果发生更改或可能发生更改，则数据库会使缓存的查询结果无效（丢弃）。在 ClickHouse 中，更改数据的操作包括在表中插入&amp;#x2F;更新&amp;#x2F;删除或折叠合并。事务一致性缓存特别适合 OLTP 数据库，例如 MySQL（在v8.0之后删除了查询缓存）和 Oracle。&lt;br&gt;在事务不一致缓存中，所有缓存条目都被分配了一个有效期，之后它们就会过期，并且基础数据在此期间仅发生很小的变化，那么查询结果中的轻微不准确是可以接受的，这种方法总体上更适合 OLAP 数据库。在一些应用场景中数据的变化假如很慢，数据库就只需要计算一次报告（由第一个 SELECT 查询表示）。可以直接从查询缓存提供进一步的查询。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;事务上不一致的缓存通常是由与数据库交互的客户端工具或代理包提供的&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&quot;二、查询缓存实操&quot;&gt;&lt;a href=&quot;#二、查询缓存实操&quot; class=&quot;headerlink&quot; title=&quot;二、查询缓存实操&quot;&gt;&lt;/a&gt;二、查询缓存实操&lt;/h1&gt;&lt;h2 id=&quot;2-1-前期准备&quot;&gt;&lt;a href=&quot;#2-1-前期准备&quot; class=&quot;headerlink&quot; title=&quot;2.1 前期准备&quot;&gt;&lt;/a&gt;2.1 前期准备&lt;/h2&gt;&lt;p&gt;这里使用 clickhouse 官方提供的 Anonymized Web Analytics Data，&lt;a</description>
          
        
      
      
      
      
      <category domain="https://blog.kpretty.tech/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/">数据库</category>
      
      
      <category domain="https://blog.kpretty.tech/tags/clickhouse/">clickhouse</category>
      
      <category domain="https://blog.kpretty.tech/tags/skill/">skill</category>
      
      <category domain="https://blog.kpretty.tech/tags/cache/">cache</category>
      
      
      <comments>https://blog.kpretty.tech/p/9498adf0.html#disqus_thread</comments>
      
    </item>
    
  </channel>
</rss>
