<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>LeoChu Space</title>
    <link>https://leochu.work/blog/</link>
    <description>Recent content on LeoChu Space</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <lastBuildDate>Mon, 13 Apr 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://leochu.work/blog/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>ChatSQL之我见</title>
      <link>https://leochu.work/blog/tech/ai/chatsql%E4%B9%8B%E6%88%91%E8%A7%81/</link>
      <pubDate>Mon, 13 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/ai/chatsql%E4%B9%8B%E6%88%91%E8%A7%81/</guid>
      <description>&lt;p&gt;这两年，AI技术越来越成熟，在很多场景上给不同的岗位提供了大量的生产力。
但是作为数据行业从业人员，其中有个场景我想泼一下冷水。
比如被讲得很热的ChatSQL。&lt;/p&gt;
&lt;p&gt;接个大模型，挂上数据库，做个对话框，让业务一句话取数，仿佛传统 BI 的门槛一下子就要被抹平。&lt;/p&gt;
&lt;p&gt;这种想象不是完全没有根据。只要场景足够干净，问题足够标准，今天的模型确实已经能生成一段相当像样的 SQL，甚至把结果也答得像模像样。&lt;/p&gt;
&lt;p&gt;但我对 ChatSQL 的判断一直比较克制。不是因为它没用，而是因为它在企业里真正要解决的，从来都不是&amp;quot;写出一条 SQL&amp;quot;这么简单。&lt;/p&gt;
&lt;h2 id=&#34;一chatsql-最难的不是生成而是语义&#34;&gt;一，ChatSQL 最难的不是生成，而是语义&lt;/h2&gt;
&lt;p&gt;很多人第一反应是：模型还不够强，等下一代就好了。&lt;/p&gt;
&lt;p&gt;这个判断的问题在于，它把 ChatSQL 的核心难点理解成了生成能力。&lt;/p&gt;
&lt;p&gt;可在企业环境里，模型最先撞墙的地方往往不是不会写 SQL，而是不知道你们公司到底在说什么。&lt;/p&gt;
&lt;p&gt;&amp;ldquo;活跃客户&amp;quot;怎么算？&lt;br&gt;
&amp;ldquo;新增付费用户&amp;quot;包不包含试用转正？&lt;br&gt;
&amp;ldquo;业绩下滑&amp;quot;看收入、利润，还是回款？&lt;/p&gt;
&lt;p&gt;这些问题本质上都不是自然语言理解问题，而是业务语义问题。模型可以把一句话翻成查询，但它翻不了一家企业内部本来就没有统一好的口径。&lt;/p&gt;
&lt;p&gt;所以 ChatSQL 如果一上来就做成&amp;quot;人话转 SQL&amp;rdquo;，最后大概率不是输在模型，而是输在语义基础太薄。&lt;/p&gt;
&lt;h2 id=&#34;二语义层很重要但它不是银弹&#34;&gt;二，语义层很重要，但它不是银弹&lt;/h2&gt;
&lt;p&gt;讲到这里，很多团队会自然转向另一个答案：那就建语义层。&lt;/p&gt;
&lt;p&gt;这个方向没错，但也很容易被误解。&lt;/p&gt;
&lt;p&gt;语义层的价值在于，把常见指标、维度、实体关系和口径规则结构化，让模型不必每次从数据库字段里重新猜业务世界。没有这层东西，系统几乎很难稳定。&lt;/p&gt;
&lt;p&gt;但语义层本身不是一个轻巧组件，它更像是一种治理成果的交付形式。&lt;/p&gt;
&lt;p&gt;换句话说，语义层不是补丁，而是地基的外化。&lt;/p&gt;
&lt;p&gt;如果企业本来就没有统一指标、没有稳定口径、没有明确的责任边界，那语义层也只是把混乱包了一层更漂亮的壳。它让问题显得更工程化，但并不会自动把问题解决。&lt;/p&gt;
&lt;p&gt;所以我更愿意把它理解成入场券，而不是终局方案。没有它，很难上线；只有它，也过不了关。&lt;/p&gt;
&lt;h2 id=&#34;三demo-证明不了产品成立&#34;&gt;三，Demo 证明不了产品成立&lt;/h2&gt;
&lt;p&gt;ChatSQL 最容易骗人的地方，就是 Demo 总是很好看。&lt;/p&gt;
&lt;p&gt;因为 Demo 里的问题通常都被精心挑过：定义清楚，范围有限，口径提前对齐，数据表也知道该怎么连。这样的条件下，模型表现出色并不奇怪。&lt;/p&gt;
&lt;p&gt;但产品成立的标准完全不是这个。&lt;/p&gt;
&lt;p&gt;真正的用户问题通常带着模糊、跳跃和上下文缺失。很多人问的不是一个可以直接翻译的问题，而是一个需要先被澄清的问题。&lt;/p&gt;
&lt;p&gt;比如：&amp;ldquo;最近业绩下滑的团队有哪些？&amp;rdquo;&lt;/p&gt;
&lt;p&gt;一个靠谱的分析师听到这句话，第一反应不会是立刻写 SQL，而是先追问。最近是多久，业绩看什么，下滑按什么基线，异常值要不要去掉，外包团队算不算。&lt;/p&gt;
&lt;p&gt;也就是说，真实分析过程本来就不是一次翻译，而是一段澄清和收敛的过程。&lt;/p&gt;
&lt;p&gt;而大多数 ChatSQL 产品，目前只接住了&amp;quot;生成查询&amp;quot;这一步，却没有接住分析师原本承担的职责：澄清、解释、回退、修正、多轮一致性。&lt;/p&gt;
&lt;p&gt;所以 Demo 证明的是模型有翻译能力，不等于产品已经具备交付能力。&lt;/p&gt;
&lt;h2 id=&#34;四chatsql-最脆弱的地方是信任不是准确率均值&#34;&gt;四，ChatSQL 最脆弱的地方是信任，不是准确率均值&lt;/h2&gt;
&lt;p&gt;很多讨论喜欢问：&amp;ldquo;准确率做到 80% 多，能不能上线？&amp;rdquo;&lt;/p&gt;
&lt;p&gt;这个问题本身问得就有点偏。&lt;/p&gt;
&lt;p&gt;如果 ChatSQL 只是给分析师自己做探索，用来找方向、提假设、少写点重复 SQL，那么它不需要像财务系统一样严苛。因为分析师本身有判断力，答偏了也知道怎么纠回来。&lt;/p&gt;
&lt;p&gt;但如果它要直接进入经营分析、财务对账、审计追责这种高责任场景，标准就完全不同了。&lt;/p&gt;
&lt;p&gt;这些场景里，决定系统能不能活下来的，不是平均准确率，而是关键问题能不能稳定答对，答错了能不能被及时发现，发现之后能不能追溯。&lt;/p&gt;
&lt;p&gt;因为用户对这类系统的信任建立得很慢，崩塌得却很快。十次答对未必能让人真正依赖它，但一次关键错误，足以让整个部门彻底弃用。&lt;/p&gt;</description>
    </item>
    <item>
      <title>谨言</title>
      <link>https://leochu.work/blog/thoughts/%E8%B0%A8%E8%A8%80/</link>
      <pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/thoughts/%E8%B0%A8%E8%A8%80/</guid>
      <description>&lt;p&gt;重要场合里最容易出问题的，往往不是不知道说什么，而是太急着回应。&lt;/p&gt;
&lt;p&gt;人一紧张，就会本能地想立刻接话，试图证明自己听懂了、反应快、能扛得住场面。但越是这样，越容易把情绪也一起说出去。语气先乱，逻辑后补，结果一句话说偏，后面十句话都要拿来修。&lt;/p&gt;
&lt;p&gt;我现在更愿意把这件事理解成一个很简单的流程：一停，二判，三说。&lt;/p&gt;
&lt;h2 id=&#34;一停&#34;&gt;一停&lt;/h2&gt;
&lt;p&gt;先停 1 秒，不急着回应。&lt;/p&gt;
&lt;p&gt;哪怕只是点头，或者先看着对方，也够了。&lt;/p&gt;
&lt;p&gt;这一秒的价值，不在于礼貌，而在于切断情绪反应。很多错话不是观点错，而是反应太快。人一旦被冒犯、被质疑、被催促，就容易直接用本能接球。那时候说出来的话，通常不是“我想表达的”，而是“我当下的应激”。&lt;/p&gt;
&lt;p&gt;这一停，就是给自己一个重新接管表达的机会。&lt;/p&gt;
&lt;h2 id=&#34;二判&#34;&gt;二判&lt;/h2&gt;
&lt;p&gt;然后快速判断一句话：对方是在要信息，还是在施压？&lt;/p&gt;
&lt;p&gt;这是最关键的一步。因为很多场合里，表面上听起来像提问，实际上并不是在认真要答案，而是在测试你、逼你表态、催你让步，或者单纯想把节奏抢走。&lt;/p&gt;
&lt;p&gt;如果对方是在要信息，那就正常回答，越清楚越好。&lt;/p&gt;
&lt;p&gt;如果对方是在施压，就别急着对抗，也别急着辩解，先把情绪收住。很多人一感觉被压，就马上想证明自己没问题，结果话越说越碎，姿态越说越低。其实对方在施压时，你最该做的不是“赢回去”，而是别让自己失去控制。&lt;/p&gt;
&lt;p&gt;先识别场景，后决定口径。&lt;/p&gt;
&lt;h2 id=&#34;三说&#34;&gt;三说&lt;/h2&gt;
&lt;p&gt;最后再说。说的时候，不靠临场发挥，靠固定结构。&lt;/p&gt;
&lt;p&gt;最简单的一种结构就是：&lt;/p&gt;
&lt;p&gt;先接一句，再说重点。&lt;/p&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;p&gt;“这个点我理解。
我这边的情况是……”&lt;/p&gt;
&lt;p&gt;或者：&lt;/p&gt;
&lt;p&gt;“这个问题可以分两点。
第一……第二… …”&lt;/p&gt;
&lt;p&gt;“接”这一下，不是示弱，而是把谈话重新拉回秩序。它先让对方知道，你听到了，也知道问题在哪。然后你再进入重点，就不会显得慌，也不会显得在乱挡。&lt;/p&gt;
&lt;p&gt;重要场合里，很多人输不是输在内容，而是输在开头那一下太乱。开头一乱，后面即使内容对，别人也会先感受到你的不稳。&lt;/p&gt;
&lt;h2 id=&#34;这个方法到底防什么&#34;&gt;这个方法到底防什么&lt;/h2&gt;
&lt;p&gt;它防的不是“不会紧张”，而是“紧张时乱说话”。&lt;/p&gt;
&lt;p&gt;紧张本身很难完全消失。越重要的场合，越在意的人，越容易有压力。真正有用的，不是要求自己毫不紧张，而是给紧张时的自己留一条动作路径。&lt;/p&gt;
&lt;p&gt;一停，是防止情绪抢跑。&lt;/p&gt;
&lt;p&gt;二判，是防止误把压力当问题来答。&lt;/p&gt;
&lt;p&gt;三说，是防止表达散掉。&lt;/p&gt;
&lt;p&gt;这三步合起来，目的只有一个：哪怕心里已经有波动，嘴上也不要失控。&lt;/p&gt;
&lt;h2 id=&#34;几个很实用的替换句&#34;&gt;几个很实用的替换句&lt;/h2&gt;
&lt;p&gt;有些话平时会说得太快，到了关键时刻尤其容易翻车。提前准备几句替换句，比临场硬扛有效得多。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;被突然追问时：&amp;ldquo;我先确认一下你的问题。&amp;rdquo;&lt;/li&gt;
&lt;li&gt;被质疑时：&amp;ldquo;这个点我理解，我把情况说完整一点。&amp;rdquo;&lt;/li&gt;
&lt;li&gt;被催着表态时：&amp;ldquo;我先说我现在能确认的部分。&amp;rdquo;&lt;/li&gt;
&lt;li&gt;场面有点压人时：&amp;ldquo;这个问题可以分开看。&amp;rdquo;&lt;/li&gt;
&lt;li&gt;自己脑子有点乱时：&amp;ldquo;我整理一下，直接说结论。&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些句子看起来都不强，但它们有一个共同作用：先把节奏拿回来。&lt;/p&gt;
&lt;h2 id=&#34;最后&#34;&gt;最后&lt;/h2&gt;
&lt;p&gt;重要场合里，真正可靠的人，往往不是反应最快的人，而是能在压力下来之后，仍然把话说稳的人。&lt;/p&gt;
&lt;p&gt;所以以后再碰到那种一紧张就想赶紧解释、赶紧回应、赶紧证明的时刻，可以只提醒自己三件事：&lt;/p&gt;
&lt;p&gt;先停一下。&lt;/p&gt;
&lt;p&gt;先判断。&lt;/p&gt;
&lt;p&gt;再开口。&lt;/p&gt;</description>
    </item>
    <item>
      <title>LDAP 简明科普</title>
      <link>https://leochu.work/blog/tech/engineering/ldap-%E7%AE%80%E6%98%8E%E7%A7%91%E6%99%AE/</link>
      <pubDate>Wed, 08 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/ldap-%E7%AE%80%E6%98%8E%E7%A7%91%E6%99%AE/</guid>
      <description>&lt;h2 id=&#34;1-什么是-ldap&#34;&gt;1. 什么是 LDAP&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;LDAP（Lightweight Directory Access Protocol）&lt;/strong&gt; 是一种用于&lt;strong&gt;查询和管理目录信息的协议&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;简单说：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;LDAP 是一个“按层级组织的用户信息数据库 + 查询方式”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;2-ldap-存什么&#34;&gt;2. LDAP 存什么&lt;/h2&gt;
&lt;p&gt;常见内容包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用户账号（用户名、ID）&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;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;3-数据结构像树&#34;&gt;3. 数据结构（像树）&lt;/h2&gt;
&lt;p&gt;LDAP 的数据是&lt;strong&gt;树状结构&lt;/strong&gt;：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph TD
A[公司] --&amp;gt; B[技术部]
A --&amp;gt; C[人事部]
B --&amp;gt; D[用户A]
B --&amp;gt; E[用户B]
C --&amp;gt; F[用户C]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;每个节点都有唯一标识（DN）。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;4-ldap-能做什么&#34;&gt;4. LDAP 能做什么&lt;/h2&gt;
&lt;ul&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;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;5-常见使用场景&#34;&gt;5. 常见使用场景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;公司统一账号系统&lt;/li&gt;
&lt;li&gt;内部系统登录（单点登录基础）&lt;/li&gt;
&lt;li&gt;权限集中管理&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;6-常见实现&#34;&gt;6. 常见实现&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;OpenLDAP&lt;/li&gt;
&lt;li&gt;Active Directory（微软）&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;7-一句话总结&#34;&gt;7. 一句话总结&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;LDAP 是一个“按树组织的用户信息数据库 + 查询协议”，用于统一管理账号和组织结构&lt;/p&gt;
&lt;/blockquote&gt;</description>
    </item>
    <item>
      <title>SSH、跳板机和隧道</title>
      <link>https://leochu.work/blog/tech/engineering/ssh%E8%B7%B3%E6%9D%BF%E6%9C%BA%E5%92%8C%E9%9A%A7%E9%81%93/</link>
      <pubDate>Wed, 08 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/ssh%E8%B7%B3%E6%9D%BF%E6%9C%BA%E5%92%8C%E9%9A%A7%E9%81%93/</guid>
      <description>&lt;h2 id=&#34;1-ssh-是什么&#34;&gt;1. SSH 是什么&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;SSH（Secure Shell）&lt;/strong&gt; 是一种用于远程登录和通信的加密协议。&lt;/p&gt;
&lt;h3 id=&#34;核心作用&#34;&gt;核心作用&lt;/h3&gt;
&lt;ul&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;/ul&gt;
&lt;h3 id=&#34;简单理解&#34;&gt;简单理解&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;就像一根“加密的远程操作线”，你在本地操作，实际在远程执行。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;图示&#34;&gt;图示&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph LR
A[本地电脑] -- SSH连接 --&amp;gt; B[远程服务器]
A --&amp;gt;|输入命令| B
B --&amp;gt;|返回结果| A
&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id=&#34;2-跳板机bastion-host是什么&#34;&gt;2. 跳板机（Bastion Host）是什么&lt;/h2&gt;
&lt;p&gt;跳板机是一台&lt;strong&gt;中间服务器&lt;/strong&gt;，用于访问内网机器。&lt;/p&gt;
&lt;h3 id=&#34;为什么需要&#34;&gt;为什么需要&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;内网服务器不能直接暴露到公网&lt;/li&gt;
&lt;li&gt;提供统一入口（安全控制、审计）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;简单理解-1&#34;&gt;简单理解&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;像“门卫”，必须先经过它，才能进入内部系统。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;图示-1&#34;&gt;图示&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph LR
A[本地电脑] --&amp;gt; B[跳板机]
B --&amp;gt; C[内网服务器]
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;常见连接方式&#34;&gt;常见连接方式&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;ssh -J user@跳板机 user@内网服务器&lt;/code&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;3-隧道ssh-tunnel是什么&#34;&gt;3. 隧道（SSH Tunnel）是什么&lt;/h2&gt;
&lt;p&gt;SSH 隧道是一种通过 SSH 转发网络流量的技术。&lt;/p&gt;
&lt;h3 id=&#34;本质&#34;&gt;本质&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;把本地请求“通过 SSH 转发到远程”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;31-本地端口转发local-forward&#34;&gt;3.1 本地端口转发（Local Forward）&lt;/h2&gt;
&lt;h3 id=&#34;示例&#34;&gt;示例&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;ssh -L 3307:127.0.0.1:3306 user@服务器&lt;/code&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>加密体系</title>
      <link>https://leochu.work/blog/tech/engineering/%E5%8A%A0%E5%AF%86%E4%BD%93%E7%B3%BB/</link>
      <pubDate>Wed, 08 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/%E5%8A%A0%E5%AF%86%E4%BD%93%E7%B3%BB/</guid>
      <description>&lt;h2 id=&#34;1-三个核心问题&#34;&gt;1. 三个核心问题&lt;/h2&gt;
&lt;p&gt;整个体系其实在解决三件事：&lt;/p&gt;
&lt;ol&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;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id=&#34;2-非对称加密公钥--私钥&#34;&gt;2. 非对称加密（公钥 / 私钥）&lt;/h2&gt;
&lt;h3 id=&#34;核心定义&#34;&gt;核心定义&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;使用一对密钥：公钥 + 私钥&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;公钥：可以公开&lt;/li&gt;
&lt;li&gt;私钥：必须保密&lt;/li&gt;
&lt;li&gt;二者不可互相推导&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&#34;两种用途关键区分&#34;&gt;两种用途（关键区分）&lt;/h3&gt;
&lt;h4 id=&#34;-加密通信&#34;&gt;① 加密通信&lt;/h4&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;graph LR
A[发送方] --&amp;gt;|公钥加密| B[密文]
B --&amp;gt; C[接收方]
C --&amp;gt;|私钥解密| D[明文]
&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h4 id=&#34;-身份认证ssh&#34;&gt;② 身份认证（SSH）&lt;/h4&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;sequenceDiagram
participant A as 客户端（私钥）
participant B as 服务器（公钥）

B-&amp;gt;&amp;gt;A: challenge
A-&amp;gt;&amp;gt;B: signature
B-&amp;gt;&amp;gt;B: 公钥验证
B-&amp;gt;&amp;gt;A: 通过/拒绝
&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h3 id=&#34;关键公式&#34;&gt;关键公式&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;signature = Sign(私钥, challenge)&lt;/code&gt;&lt;br&gt;
&lt;code&gt;Verify(公钥, challenge, signature) = true&lt;/code&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;本质总结&#34;&gt;本质总结&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;私钥负责“生成证明”，公钥负责“验证证明”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;3-ssh基于签名的认证机制&#34;&gt;3. SSH：基于签名的认证机制&lt;/h2&gt;
&lt;h3 id=&#34;文件结构&#34;&gt;文件结构&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;~/.ssh/id_ed25519      &lt;span style=&#34;color:#75715e&#34;&gt;# 私钥&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;~/.ssh/id_ed25519.pub  &lt;span style=&#34;color:#75715e&#34;&gt;# 公钥&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;~/.ssh/authorized_keys &lt;span style=&#34;color:#75715e&#34;&gt;# 服务器保存公钥&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id=&#34;免密登录本质&#34;&gt;免密登录本质&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;服务器信任“某个公钥”，允许对应私钥登录&lt;/p&gt;</description>
    </item>
    <item>
      <title>再谈洞穴时间</title>
      <link>https://leochu.work/blog/thoughts/%E5%86%8D%E8%B0%88%E6%B4%9E%E7%A9%B4%E6%97%B6%E9%97%B4/</link>
      <pubDate>Tue, 07 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/thoughts/%E5%86%8D%E8%B0%88%E6%B4%9E%E7%A9%B4%E6%97%B6%E9%97%B4/</guid>
      <description>&lt;p&gt;之前那篇关于“洞穴时间”的文章，言辞可能过于激烈，观点也有失偏颇。&lt;/p&gt;
&lt;p&gt;很多人把“洞穴时间”理解为男人的本能需求，是需要独处、放空、自我修复的一种方式。&lt;/p&gt;
&lt;p&gt;但这次，我想换个更刺耳的说法——女人见不得男人开心。&lt;/p&gt;
&lt;p&gt;关键点并不在于“见不得”本身，而是——当男人的快乐不包含她时，这种快乐，往往会变得不被允许、不被理解，甚至需要被纠正。&lt;/p&gt;
&lt;p&gt;他和朋友聚会很开心，会被一遍遍追问、被扫兴； 他钓鱼很开心，会被打断、被催促，直到那点兴致被消磨干净； 他打游戏很开心，会被上升为浪费时间、不务正业。&lt;/p&gt;
&lt;p&gt;甚至，就像前文那种情况—— 他只能在她睡着后才能安心打会游戏，不然可能被视为一种“冷落”、一种“有问题的行为”，迟早要被翻出来对账。&lt;/p&gt;
&lt;p&gt;于是，开心本身，开始变成一件有风险的事。&lt;/p&gt;
&lt;p&gt;男人只能把这些不被允许的轻松、松弛、无负担的时刻，压缩进深夜，压缩进车里那半小时，压缩进那盏不关的灯里。&lt;/p&gt;
&lt;p&gt;所谓“洞穴时间”，不再只是独处，而是被挤压出来的安全空间。&lt;/p&gt;
&lt;p&gt;最近读了点社会心理学，书上说这种冲突并不罕见。 男性更倾向于通过“切换场景”来恢复精力，而女性更倾向于通过“维持连接”来获得安全感。当一方把“离开”理解为放松，另一方却把它解读为疏远，冲突就产生了。&lt;/p&gt;
&lt;p&gt;但问题在于—— 如果一段关系要求一个人只能在关系之内快乐，那这段关系本身，就已经开始变得空气稀薄。&lt;/p&gt;
&lt;p&gt;一个更健康的状态应该是： 你可以参与我的快乐，但你不需要垄断它； 我可以离开一会儿，但不是在逃离你。&lt;/p&gt;
&lt;p&gt;真正稳固的关系，不是没有“洞穴时间”， 而是—— 即使不在彼此身边，也不会因此被怀疑、被惩罚、被剥夺获取快乐的权利。&lt;/p&gt;
&lt;p&gt;附: &lt;a href=&#34;https://leochu.work/blog/reading/%E7%94%B7%E4%BA%BA%E6%9D%A5%E8%87%AA%E7%81%AB%E6%98%9F%E5%A5%B3%E4%BA%BA%E6%9D%A5%E8%87%AA%E9%87%91%E6%98%9F/&#34;&gt;男人来自火星女人来自金星&lt;/a&gt; &lt;a href=&#34;https://leochu.work/blog/reading/%E4%BA%B2%E5%AF%86%E5%85%B3%E7%B3%BB/&#34;&gt;亲密关系&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>AI编程的本质不是写代码，而是GSD</title>
      <link>https://leochu.work/blog/tech/ai/ai%E7%BC%96%E7%A8%8B%E7%9A%84%E6%9C%AC%E8%B4%A8%E4%B8%8D%E6%98%AF%E5%86%99%E4%BB%A3%E7%A0%81%E8%80%8C%E6%98%AFgsd/</link>
      <pubDate>Mon, 06 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/ai/ai%E7%BC%96%E7%A8%8B%E7%9A%84%E6%9C%AC%E8%B4%A8%E4%B8%8D%E6%98%AF%E5%86%99%E4%BB%A3%E7%A0%81%E8%80%8C%E6%98%AFgsd/</guid>
      <description>&lt;p&gt;很多人谈 AI 编程，谈到最后都会滑向两个方向：要么研究 prompt 话术，要么研究工具排行榜。可真正把项目做下来之后会发现，决定结果的往往不是模型有多强，而是任务有没有被稳定推进。&lt;/p&gt;
&lt;p&gt;所以我越来越确信，AI 编程的本质不是写代码，而是 &lt;strong&gt;GSD: Get Shit Done&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;这不是一句鸡血口号，而是一种工作判断。AI 最擅长的是局部生成，人最不可替代的是定义目标、控制边界、校验结果、决定下一步。谁负责把事情做完，谁就掌握了 AI 编程的核心。&lt;/p&gt;
&lt;h2 id=&#34;什么是-gsd&#34;&gt;什么是 GSD&lt;/h2&gt;
&lt;p&gt;GSD 本来就不是 AI 圈专属概念，它说的是一种执行方法：少空转，少沉迷完美方案，尽快把任务拆开、落地、验证、收口。&lt;/p&gt;
&lt;p&gt;它在 AI 编程里尤其重要，因为 AI 把“产出代码”这件事变得太便宜了。过去写错一段代码，要付出几十分钟；现在模型可以在错误方向上连续输出三轮，还都看起来像那么回事。于是，真正稀缺的能力不再是“产出更多”，而是“识别什么值得继续推进”。&lt;/p&gt;
&lt;p&gt;从这个角度看，AI 时代没有削弱软件工程，反而把它最硬的那一面暴露出来了：任务拆分、上下文管理、验收标准、回滚意识、重构节奏，这些东西一个都没消失。&lt;/p&gt;
&lt;h2 id=&#34;ai-编程真正的问题&#34;&gt;AI 编程真正的问题&lt;/h2&gt;
&lt;p&gt;AI 编程当然快，但快不等于高效。它最常见的问题有三个。&lt;/p&gt;
&lt;h3 id=&#34;低效&#34;&gt;低效&lt;/h3&gt;
&lt;p&gt;表面上，模型替你写了很多代码；实际上，你只是把时间从“自己写”换成了“审它、修它、补上下文”。如果生成规模大于验证能力，效率往往是下降的。&lt;/p&gt;
&lt;h3 id=&#34;反复试错&#34;&gt;反复试错&lt;/h3&gt;
&lt;p&gt;很多人以为自己在迭代，实际上只是陷入了“生成一版、修一版、再修一版”的循环。每一轮都像在前进，但系统并没有更接近完成状态，只是在不断清理上一轮制造的噪音。&lt;/p&gt;
&lt;h3 id=&#34;上下文失真&#34;&gt;上下文失真&lt;/h3&gt;
&lt;p&gt;模型对项目的理解不是稳定存在的，它只是在当前上下文里做局部推断。上下文一长、一脏、一旧，就会开始忘约定、乱覆盖、重复犯错。很多所谓“模型不靠谱”，本质上是上下文早就失控了。&lt;/p&gt;
&lt;p&gt;所以 AI 编程的问题，从来不只是模型问题，更是工作流问题。&lt;/p&gt;
&lt;h2 id=&#34;gsd-的核心原则&#34;&gt;GSD 的核心原则&lt;/h2&gt;
&lt;h3 id=&#34;拆任务&#34;&gt;拆任务&lt;/h3&gt;
&lt;p&gt;不要让 AI 一次处理一个模糊的大目标。大任务一旦没有边界，生成结果几乎注定失真。AI 适合吃小而明确的问题，不适合替你发明完整项目。&lt;/p&gt;
&lt;h3 id=&#34;快速验证&#34;&gt;快速验证&lt;/h3&gt;
&lt;p&gt;每走一步，都要尽快确认这一步到底有没有真的往前。能不能运行，输出对不对，页面能不能打开，接口是不是污染了别的模块。这些检查越便宜，闭环越短，任务越稳。&lt;/p&gt;
&lt;h3 id=&#34;循环迭代&#34;&gt;循环迭代&lt;/h3&gt;
&lt;p&gt;AI 编程最好的节奏不是一次性生成大而全，而是持续压缩闭环：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;给清晰目标&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;生成最小结果&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;立刻验证&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;根据结果继续下一轮&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;GSD 的价值，就在于它把“生成”放回“推进”之内，而不是把生成本身误当成进展。&lt;/p&gt;
&lt;h2 id=&#34;一个够用的标准流程&#34;&gt;一个够用的标准流程&lt;/h2&gt;
&lt;p&gt;如果要把 GSD 落到 AI 编程里，我觉得最实用的流程就是五步：&lt;/p&gt;
&lt;h3 id=&#34;需求&#34;&gt;需求&lt;/h3&gt;
&lt;p&gt;先把目标说清楚。不是“我想做个什么”，而是输入输出是什么、约束是什么、做到什么算完成。没有完成标准，后面的每一轮生成都会发飘。&lt;/p&gt;
&lt;h3 id=&#34;prompt&#34;&gt;Prompt&lt;/h3&gt;
&lt;p&gt;Prompt 的重点不是修辞，而是约束。你至少要说清背景、任务、涉及范围、禁止事项和输出形式。不给边界，模型就会自动脑补。&lt;/p&gt;</description>
    </item>
    <item>
      <title>彩虹</title>
      <link>https://leochu.work/blog/thoughts/%E5%BD%A9%E8%99%B9/</link>
      <pubDate>Mon, 06 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/thoughts/%E5%BD%A9%E8%99%B9/</guid>
      <description>&lt;p&gt;哪里有彩虹告诉我 能不能把我的愿望还给我 为什么天这么安静 所有的云都跑到我这里 有没有口罩一个给我 释怀说了太多就成真不了 也许时间是一种解药 也是我现在正服下的毒药 看不见你的笑 我怎么睡得着 你的声音这么近我却抱不到 没有地球太阳还是会绕 没有理由我也能自己走 你要离开 我知道很简单 你说依赖 是我们的阻碍 就算放开 但能不能别没收我的爱 当作我最后才明白&lt;/p&gt;</description>
    </item>
    <item>
      <title>codex类claude提示词约束</title>
      <link>https://leochu.work/blog/tech/ai/codex%E7%B1%BBclaude%E6%8F%90%E7%A4%BA%E8%AF%8D%E7%BA%A6%E6%9D%9F/</link>
      <pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/ai/codex%E7%B1%BBclaude%E6%8F%90%E7%A4%BA%E8%AF%8D%E7%BA%A6%E6%9D%9F/</guid>
      <description>&lt;p&gt;你现在是一个软件工程师助手，需要与我协作完成开发任务。&lt;/p&gt;
&lt;p&gt;请严格遵守以下流程：&lt;/p&gt;
&lt;p&gt;【阶段一：分析与方案】&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;不要直接修改代码&lt;/li&gt;
&lt;li&gt;先完整理解需求和现有代码结构&lt;/li&gt;
&lt;li&gt;给出一个详细的实现方案，包括：
&lt;ul&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;/ul&gt;
&lt;/li&gt;
&lt;li&gt;输出清晰的分步骤计划（Step 1, Step 2, &amp;hellip;）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;完成后，停止执行，等待我的确认。&lt;/p&gt;
&lt;p&gt;【阶段二：执行（必须等我确认后）】&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;严格按照确认的步骤逐步执行&lt;/li&gt;
&lt;li&gt;每执行一步都需要：
&lt;ul&gt;
&lt;li&gt;说明本步做了什么&lt;/li&gt;
&lt;li&gt;展示具体代码改动（diff）&lt;/li&gt;
&lt;li&gt;不要一次性完成所有步骤&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;【约束规则】&lt;/p&gt;
&lt;ul&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;/ul&gt;
&lt;p&gt;【输出要求】&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;结构清晰，步骤编号明确&lt;/li&gt;
&lt;li&gt;解释要简洁但完整&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    <item>
      <title>集群常用脚本</title>
      <link>https://leochu.work/blog/tech/engineering/%E9%9B%86%E7%BE%A4%E5%B8%B8%E7%94%A8%E8%84%9A%E6%9C%AC/</link>
      <pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/%E9%9B%86%E7%BE%A4%E5%B8%B8%E7%94%A8%E8%84%9A%E6%9C%AC/</guid>
      <description>&lt;p&gt;多重执行xcall.sh&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/bin/bash

# 遍历所有节点（集群主机列表）
for i in cdhmaster01 cdhmaster02 cdhmaster03 cdhnode01 cdhnode02 cdhnode03
do
  # 打印当前正在操作的主机，方便区分输出
  echo &amp;#34;--------- $i ----------&amp;#34;

  # 通过 ssh 在远程主机执行传入的命令
  # &amp;#34;$*&amp;#34; 表示把所有参数当作一个整体传过去
  # 例如：./xcall.sh pwd
  # 实际执行：ssh cdhmaster01 &amp;#34;pwd&amp;#34;
  ssh $i &amp;#34;$*&amp;#34;
done
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;集群分发xsync.sh&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/bin/bash

if [ $# -eq 0 ]; then
  echo &amp;#34;Usage: $0  [more files_or_dirs]&amp;#34;
  exit 1
fi

hosts=(cdhmaster01 cdhmaster02 cdhmaster03 cdhnode01 cdhnode02 cdhnode03)
user=$(whoami)

for src in &amp;#34;$@&amp;#34;
do
  if [ ! -e &amp;#34;$src&amp;#34; ]; then
    echo &amp;#34;Not found: $src&amp;#34;
    continue
  fi

  abs_src=$(readlink -f &amp;#34;$src&amp;#34;)
  name=$(basename &amp;#34;$abs_src&amp;#34;)
  parent=$(dirname &amp;#34;$abs_src&amp;#34;)

  for host in &amp;#34;${hosts[@]}&amp;#34;
  do
    echo &amp;#34;===== $host =====&amp;#34;

    ssh &amp;#34;$host&amp;#34; &amp;#34;mkdir -p &amp;#39;$parent&amp;#39;&amp;#34;

    if [ -d &amp;#34;$abs_src&amp;#34; ]; then
      rsync -av &amp;#34;$abs_src&amp;#34; &amp;#34;$user@$host:$parent/&amp;#34;
    else
      rsync -av &amp;#34;$abs_src&amp;#34; &amp;#34;$user@$host:$parent/&amp;#34;
    fi
  done
done
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>博客标签设计</title>
      <link>https://leochu.work/blog/ideas/%E5%8D%9A%E5%AE%A2%E6%A0%87%E7%AD%BE%E8%AE%BE%E8%AE%A1/</link>
      <pubDate>Wed, 01 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/ideas/%E5%8D%9A%E5%AE%A2%E6%A0%87%E7%AD%BE%E8%AE%BE%E8%AE%A1/</guid>
      <description>&lt;h2 id=&#34;一设计原则&#34;&gt;一、设计原则&lt;/h2&gt;
&lt;p&gt;标签用于表达文章的“内容特征”，而不是分类。&lt;/p&gt;
&lt;p&gt;分类（categories）用于表示文章所属目录（放在哪），标签（tags）用于描述文章内容（讲什么）。&lt;/p&gt;
&lt;p&gt;标签统一为单层结构，不做层级划分。&lt;/p&gt;
&lt;p&gt;标签体系同时服务两种需求：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;浏览：快速理解文章内容&lt;/li&gt;
&lt;li&gt;检索：精确定位知识点&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;二标签分类逻辑分层&#34;&gt;二、标签分类（逻辑分层）&lt;/h2&gt;
&lt;h3 id=&#34;1-技术类标签核心索引&#34;&gt;1. 技术类标签（核心索引）&lt;/h3&gt;
&lt;p&gt;用于标识具体技术或组件，可包含低频标签：&lt;/p&gt;
&lt;p&gt;JVM&lt;br&gt;
Java&lt;br&gt;
Python&lt;br&gt;
Django&lt;br&gt;
Git&lt;br&gt;
Maven&lt;br&gt;
Linux&lt;/p&gt;
&lt;p&gt;Hive&lt;br&gt;
Spark&lt;br&gt;
Kafka&lt;br&gt;
Flink&lt;br&gt;
Hadoop&lt;br&gt;
Yarn&lt;br&gt;
Flume&lt;br&gt;
Presto
ClickHouse&lt;/p&gt;
&lt;p&gt;MySQL&lt;br&gt;
MongoDB&lt;br&gt;
Elasticsearch&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;说明：&lt;br&gt;
技术标签允许低频存在，用于精确检索，不需要强制精简。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id=&#34;2-内容类型标签高频-&#34;&gt;2. 内容类型标签（高频 ⭐）&lt;/h3&gt;
&lt;p&gt;用于标识文章表达形式：&lt;/p&gt;
&lt;p&gt;速查&lt;br&gt;
总结&lt;br&gt;
原理&lt;br&gt;
教程&lt;br&gt;
配置&lt;br&gt;
调优&lt;br&gt;
源码&lt;/p&gt;
&lt;p&gt;笔记&lt;br&gt;
摘录&lt;br&gt;
记录&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;3-场景类标签中频&#34;&gt;3. 场景类标签（中频）&lt;/h3&gt;
&lt;p&gt;用于标识问题或使用场景：&lt;/p&gt;
&lt;p&gt;踩坑&lt;br&gt;
实战&lt;br&gt;
排错&lt;br&gt;
面试&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&#34;4-通用认知标签非技术内容-&#34;&gt;4. 通用认知标签（非技术内容 ⭐）&lt;/h3&gt;
&lt;p&gt;用于 reading / thoughts / ideas：&lt;/p&gt;
&lt;p&gt;思考&lt;br&gt;
认知&lt;br&gt;
学习&lt;/p&gt;
&lt;p&gt;产品&lt;br&gt;
副业&lt;/p&gt;
&lt;p&gt;灵感&lt;br&gt;
想法&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;三使用规范重点&#34;&gt;三、使用规范（重点）&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;每篇文章建议使用 2～5 个标签&lt;/li&gt;
&lt;li&gt;建议组合：
&lt;ul&gt;
&lt;li&gt;1～2 个技术标签（可低频）&lt;/li&gt;
&lt;li&gt;1 个类型标签（必选）&lt;/li&gt;
&lt;li&gt;可选 1 个场景或认知标签&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;技术标签优先表达“具体技术点”&lt;/li&gt;
&lt;li&gt;类型标签控制文章表达形式（避免缺失）&lt;/li&gt;
&lt;li&gt;避免重复语义标签（如：调优 vs 优化，仅保留调优）&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id=&#34;四示例&#34;&gt;四、示例&lt;/h2&gt;
&lt;h3 id=&#34;示例-1git-命令速查&#34;&gt;示例 1：Git 命令速查&lt;/h3&gt;
&lt;p&gt;tags:&lt;/p&gt;</description>
    </item>
    <item>
      <title>两种talk</title>
      <link>https://leochu.work/blog/thoughts/%E4%B8%A4%E7%A7%8Dtalk/</link>
      <pubDate>Wed, 01 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/thoughts/%E4%B8%A4%E7%A7%8Dtalk/</guid>
      <description>&lt;p&gt;有人说，衡量两个人关系深度的方式，是看他们能聊到多深，也能玩到多野。&lt;/p&gt;
&lt;p&gt;Deep talk 是那种聊到凌晨两点还不困的对话。聊彼此真正在意什么，聊对这个世界有什么判断，聊价值观里哪些东西是绝对不能妥协的。不是辩论，不是说服，是两个人把各自的三观摊开来放在一起比对——发现某些地方高度重合时，那种安心感是很难言说的。能 deep talk 的人，是真的愿意被你看见的人。&lt;/p&gt;
&lt;p&gt;Dirty talk 是另一种坦诚。它需要放下羞耻感，需要信任，需要知道对方不会因为你说了什么奇奇怪怪的话就用异样的眼光看你。它本质上也是一种语言的亲密——用语言触碰对方，用玩笑和挑逗确认彼此之间那道边界是可以随意跨过的。&lt;/p&gt;
&lt;p&gt;很多人能做到其中一件，却做不到两件同时。有人聊得了人生意义，一到床上就哑口无言；有人嬉皮笑脸没个正经，却永远不让你靠近他真实的内心。两件事都能做到的人，其实是说：我在你面前，没有什么是需要表演的。&lt;/p&gt;
&lt;p&gt;这挺难得的。&lt;/p&gt;
&lt;p&gt;不是每段关系都能长出这种空间。它需要时间，需要一次次试探之后积累的安全感，需要两个人都愿意先放下一点防备。有时候是一个人先开口说了一句很傻的话，另一个人没有嘲笑，于是就又多了一点胆子。慢慢的，那个空间就有了。&lt;/p&gt;
&lt;p&gt;所以如果你身边有这样一个人——能跟你认真聊，也能跟你不正经。&lt;/p&gt;
&lt;p&gt;这不是标配，这是运气。&lt;/p&gt;
&lt;p&gt;(享福啦)&lt;/p&gt;</description>
    </item>
    <item>
      <title>HDFS更改数据目录导致NameNode无法启动</title>
      <link>https://leochu.work/blog/tech/bigdata/hdfs%E6%9B%B4%E6%94%B9%E6%95%B0%E6%8D%AE%E7%9B%AE%E5%BD%95%E5%AF%BC%E8%87%B4namenode%E6%97%A0%E6%B3%95%E5%90%AF%E5%8A%A8/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/hdfs%E6%9B%B4%E6%94%B9%E6%95%B0%E6%8D%AE%E7%9B%AE%E5%BD%95%E5%AF%BC%E8%87%B4namenode%E6%97%A0%E6%B3%95%E5%90%AF%E5%8A%A8/</guid>
      <description>&lt;h1 id=&#34;20260326-hdfs更改数据目录导致namenode无法启动&#34;&gt;20260326 HDFS更改数据目录导致NameNode无法启动&lt;/h1&gt;
&lt;h2 id=&#34;问题描述&#34;&gt;问题描述：&lt;/h2&gt;
&lt;p&gt;由于一开始硬盘还未挂载目录，安装cdh时，配置hdfs相关数据目录就用了默认的系统盘下的目录，如下&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/data/dfs/nn /data/dfs/jn /data/dfs/dn&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;后面数据盘挂载在/hadoop/data1/下，固将hdfs的数据目录改为&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/hadoop/data1/dfs/nn /hadoop/data1/dfs/jn /hadoop/data1/dfs/dn&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;重新启动hdfs，报错，分为三类：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;nameNode 无法格式化&lt;/li&gt;
&lt;li&gt;丢失块信息100%&lt;/li&gt;
&lt;li&gt;Cloudera Manager 无法检测 HDFS 健康状态&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;解决&#34;&gt;解决：&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;停掉hdfs所有服务&lt;/li&gt;
&lt;li&gt;清空&lt;code&gt;/hadoop/data1/dfs/nn /hadoop/data1/dfs/jn /hadoop/data1/dfs/dn&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;启动dataNode，failoverController 等服务（除NameNode，journalNode外）&lt;/li&gt;
&lt;li&gt;对activity NameNode执行format操作&lt;img loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/019d28d7-9af8-7238-a7f4-dd472d172e28-image.png&#34;&gt;&lt;/li&gt;
&lt;li&gt;启动所有journalNode&lt;/li&gt;
&lt;li&gt;启动activity NameNode&lt;/li&gt;
&lt;li&gt;对Standby NameNode执行Bootstrap Standby操作&lt;img loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/019d28dc-56f9-7688-875c-c416075ef63c-image.png&#34;&gt;&lt;/li&gt;
&lt;li&gt;启动Standby NameNode&lt;/li&gt;
&lt;li&gt;ssh客户端以hdfs用户执行&lt;code&gt;hdfs dfs -chmod -R 777 /data/tmp&lt;/code&gt; 等命令,完成以下目录创建及赋权,后续通过ranger做权限收口&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[hdfs@cdhmaster02 ~]$ hdfs dfs -ls Found 3 items
drwxrwxrwt   - hdfs supergroup          0 2026-03-26 12:31 /data
drwxrwxrwt   - hdfs supergroup          0 2026-03-26 17:25 /tmp
drwxr-xr-x   - hdfs supergroup          0 2026-03-26 17:24 /user
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;注意事项&#34;&gt;注意事项：&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;操作顺序不可颠倒，否则可能导致 NameNode 或 JournalNode 数据不一致&lt;/li&gt;
&lt;li&gt;不能对 Standby NameNode 执行 format，否则会破坏 HA 集群&lt;/li&gt;
&lt;li&gt;**(重要)**清空目录操作仅限于尚未存储业务数据的集群或测试环境&lt;/li&gt;
&lt;li&gt;如果要迁移已有数据的数据目录，则需要&lt;code&gt;rsync -avh /data/dfs/nn/ /hadoop/data1/dfs/nn/&lt;/code&gt;类似命令&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;原因解释&#34;&gt;原因解释：&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;NameNode 无法格式化&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;HDFS 的 HA 模式下，Active NameNode 的元数据（fsimage + edits）必须与 Quorum Journal Nodes 保持一致。&lt;/li&gt;
&lt;li&gt;修改 HDFS 存储目录后，如果 JournalNode 目录仍保留旧数据或未初始化，NameNode 在检查 quorum 时会发现元数据不匹配，因此无法格式化。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;关键点&lt;/strong&gt;：只允许对 Active NameNode 格式化，Standby NameNode 或 JournalNode 不能直接 format，否则会破坏 HA 的一致性机制。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;丢失块信息 100%&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;DataNode 存储目录修改后，旧数据无法被 NameNode 正确识别，因为 NameNode 的 fsimage 中没有对应块信息。&lt;/li&gt;
&lt;li&gt;NameNode 启动时会扫描 DataNode 上报的块，如果目录未初始化或数据不匹配，则所有块都被标记为丢失，从而导致 CM 显示 100% missing blocks。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;关键点&lt;/strong&gt;：HDFS 的块映射严格依赖 NameNode 的元数据，DataNode 目录未同步会造成“逻辑丢失”，即使物理数据存在。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cloudera Manager 无法检测 HDFS&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;CM Canary 测试依赖基本的 HDFS I/O 操作（创建、写入、读取、删除文件）。&lt;/li&gt;
&lt;li&gt;当 NameNode 在安全模式或丢失块状态下，读写请求无法完成，Canary 测试失败，导致 CM 显示健康异常。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;关键点&lt;/strong&gt;：CM 健康检测反映的是 NameNode 和 DataNode 的可用性与一致性，而非磁盘本身状态。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;操作顺序要求严格&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Active NameNode 必须先格式化并启动，使元数据初始化完成。&lt;/li&gt;
&lt;li&gt;JournalNode 启动后才能形成 Quorum，保证 HA 的 edit log 复制。&lt;/li&gt;
&lt;li&gt;Standby NameNode 只能通过 &lt;strong&gt;Bootstrap Standby&lt;/strong&gt; 从 Active NameNode 同步元数据，否则会破坏 HA 的一致性，导致集群无法启动。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;关键点&lt;/strong&gt;：HDFS HA 的核心机制是 edit log 的 quorum 写入与 NameNode 状态同步，顺序错误会导致集群不可用。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;</description>
    </item>
    <item>
      <title>叫魂</title>
      <link>https://leochu.work/blog/reading/%E5%8F%AB%E9%AD%82/</link>
      <pubDate>Tue, 03 Mar 2026 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/reading/%E5%8F%AB%E9%AD%82/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;孔飞力《叫魂》。核心观点：一场看似荒诞的民间恐慌，之所以会扩大成全国性政治事件，是因为它精准触发了国家、社会与人心深处的脆弱结构。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;核心观点&#34;&gt;核心观点&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;谣言的传播并不靠真实性，而靠可附着性。&lt;/strong&gt; 一个说法只要足够符合时代焦虑，就会迅速扩散。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;国家机器会放大某些恐慌。&lt;/strong&gt; 当权力系统把模糊恐惧上升为正式治理对象时，事情就不再只是民间流言，而会演变成制度性运动。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;底层社会的不安会借由荒诞形式表现出来。&lt;/strong&gt; “叫魂”不是单纯迷信，而是一种集体焦虑的出口。&lt;/p&gt;
&lt;h2 id=&#34;印象较深的部分&#34;&gt;印象较深的部分&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;很多看起来荒唐的事件，背后都埋着真实的不安全感。&lt;/strong&gt; 人们害怕的未必是谣言本身，而是自己无法掌控的生活处境。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;统治者对秩序失控的恐惧，与百姓对生活失控的恐惧，会在同一事件里相互放大。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;读后感&#34;&gt;读后感&lt;/h2&gt;
&lt;p&gt;讲了一整套机制：恐慌怎么形成，怎么扩散，又怎么被权力接手。&lt;/p&gt;
&lt;p&gt;合上书之后，这个判断会变得更清楚：很多群体性狂热都不是偶然，它们总有适合生长的土壤。&lt;/p&gt;</description>
    </item>
    <item>
      <title>PostgreSQL同步HDFS</title>
      <link>https://leochu.work/blog/tech/bigdata/postgresql%E5%90%8C%E6%AD%A5hdfs/</link>
      <pubDate>Thu, 12 Feb 2026 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/postgresql%E5%90%8C%E6%AD%A5hdfs/</guid>
      <description>&lt;p&gt;1.使用datax同步数据&lt;/p&gt;
&lt;p&gt;2.模板json(已配置hdfs ha)：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;job&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;content&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;reader&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;postgresqlreader&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;parameter&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;username&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;hs_sync&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;password&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Pass2025&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;column&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;order_date&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;day&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;iso_day_of_week&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;weekday_cn&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;weekday_en&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;weekday_short&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;is_weekend&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;iso_week&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;month&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;month_cn&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;month_en_full&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;month_en_short&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;quarter&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;year&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        ],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;connection&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;table&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;dim_calendar&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                ],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;jdbcUrl&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;jdbc:postgresql://100.64.0.10:25432/hs_sync_data&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        ],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;fetchSize&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;1000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;writer&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;hdfswriter&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;parameter&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;defaultFS&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;hdfs://nameservice1&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;hadoopConfig&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;dfs.nameservices&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;nameservice1&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;dfs.ha.namenodes.nameservice1&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;nn1,nn2&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;dfs.namenode.rpc-address.nameservice1.nn1&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;192.168.33.61:8020&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;dfs.namenode.rpc-address.nameservice1.nn2&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;192.168.33.62:8020&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;dfs.client.failover.proxy.provider.nameservice1&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;fileType&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;orc&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;path&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/tmp/data/test/&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;fileName&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;dim_calendar&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;writeMode&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;truncate&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;column&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;order_date&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;date&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;day&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;smallint&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;iso_day_of_week&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;smallint&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;weekday_cn&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;string&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;weekday_en&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;string&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;weekday_short&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;string&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;is_weekend&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;boolean&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;iso_week&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;smallint&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;month&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;smallint&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;month_cn&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;string&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;month_en_full&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;string&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;month_en_short&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;string&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;quarter&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;string&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;year&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;smallint&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        ],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;fieldDelimiter&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;\t&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;maxFileSize&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;134217728&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;encoding&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;UTF-8&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;setting&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;speed&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;channel&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;errorLimit&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;record&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;percentage&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0.02&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;retry&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;limit&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;interval&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;5000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>CDH基础配置及优化</title>
      <link>https://leochu.work/blog/tech/bigdata/cdh%E5%9F%BA%E7%A1%80%E9%85%8D%E7%BD%AE%E5%8F%8A%E4%BC%98%E5%8C%96/</link>
      <pubDate>Sun, 01 Feb 2026 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/cdh%E5%9F%BA%E7%A1%80%E9%85%8D%E7%BD%AE%E5%8F%8A%E4%BC%98%E5%8C%96/</guid>
      <description>&lt;h1 id=&#34;一hive中文注释乱码&#34;&gt;一、hive中文注释乱码&lt;/h1&gt;
&lt;h2 id=&#34;1设置-hive-元数据库字符集&#34;&gt;&lt;em&gt;1、设置 hive 元数据库字符集&lt;/em&gt;&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;show create database hive;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/019d0a6a-72c9-7608-ac3a-0a57f498e4fd-image.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;查看为 utf8，需变更为 latin1&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;alter database hive character set latin1; &lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/019d0a6b-d35a-7499-96cd-9281218f8e88-image.png&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;2更改如下表字段为字符集编码为-utf8&#34;&gt;&lt;em&gt;2、更改如下表字段为字符集编码为 utf8&lt;/em&gt;&lt;/h2&gt;
&lt;p&gt;①修改表字段注解和表注解&lt;br&gt;
alter table COLUMNS_V2 modify column COMMENT varchar(256) character set utf8;&lt;br&gt;
alter table TABLE_PARAMS modify column PARAM_VALUE varchar(4000) character set utf8;&lt;br&gt;
② 修改分区字段注解：&lt;br&gt;
alter table PARTITION_PARAMS modify column PARAM_VALUE varchar(4000) character set utf8 ;&lt;br&gt;
alter table PARTITION_KEYS modify column PKEY_COMMENT varchar(4000) character set utf8;&lt;br&gt;
③修改索引注解：&lt;br&gt;
alter table INDEX_PARAMS modify column PARAM_VALUE varchar(4000) character set utf8;&lt;/p&gt;</description>
    </item>
    <item>
      <title>linux系统级优化</title>
      <link>https://leochu.work/blog/tech/bigdata/linux%E7%B3%BB%E7%BB%9F%E7%BA%A7%E4%BC%98%E5%8C%96/</link>
      <pubDate>Sat, 31 Jan 2026 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/linux%E7%B3%BB%E7%BB%9F%E7%BA%A7%E4%BC%98%E5%8C%96/</guid>
      <description>&lt;h2 id=&#34;一在cdhcm部署时已经做了部分系统优化&#34;&gt;一、在cdh+cm部署时，已经做了部分系统优化&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;ssh双向免密&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;配置时间同步服务（本次没用ntpd，用的是chrony）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;禁用透明大页、碎片整理：THP (Transparent Huge Pages)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;禁用内存交换swap（常用0或1）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;二hadoop集群推荐内核参数&#34;&gt;二、hadoop集群推荐内核参数：&lt;/h2&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;&lt;strong&gt;参数名称&lt;/strong&gt;&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;默认值&lt;/strong&gt;&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;文件系统参数&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;fs.file-max&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;6815744&lt;/td&gt;
          &lt;td&gt;系统最大文件描述符数量（所有进程可打开文件总数上限）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;fs.aio-max-nr&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;1048576&lt;/td&gt;
          &lt;td&gt;异步I/O请求的最大并发数（影响高并发场景性能）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;网络核心参数&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;net.core.rmem_default&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;262144&lt;/td&gt;
          &lt;td&gt;TCP接收缓冲区&lt;strong&gt;默认大小&lt;/strong&gt;（256KB）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;net.core.wmem_default&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;262144&lt;/td&gt;
          &lt;td&gt;TCP发送缓冲区&lt;strong&gt;默认大小&lt;/strong&gt;（256KB）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;net.core.rmem_max&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;16777216&lt;/td&gt;
          &lt;td&gt;TCP接收缓冲区&lt;strong&gt;最大允许值&lt;/strong&gt;（16MB）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;net.core.wmem_max&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;16777216&lt;/td&gt;
          &lt;td&gt;TCP发送缓冲区&lt;strong&gt;最大允许值&lt;/strong&gt;（16MB）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;TCP协议栈参数&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;net.ipv4.tcp_rmem&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;4096 262144 16777216&lt;/td&gt;
          &lt;td&gt;接收窗口尺寸：• 最小值4KB• 默认值256KB• 最大值16MB&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;net.ipv4.tcp_wmem&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;4096 262144 16777216&lt;/td&gt;
          &lt;td&gt;发送窗口尺寸：• 最小值4KB• 默认值256KB• 最大值16MB&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;查看当前内核配置：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sysctl -e fs.file-max fs.aio-max-nr &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; net.core.rmem_default net.core.wmem_default &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; net.core.rmem_max net.core.wmem_max &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; net.ipv4.tcp_rmem net.ipv4.tcp_wmem 2&amp;gt;/dev/nulll
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/019d1e9d-a8aa-71fa-bc02-15c30fb69345-image.png&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>CDH6.3.2集群部署</title>
      <link>https://leochu.work/blog/tech/bigdata/cdh6.3.2%E9%9B%86%E7%BE%A4%E9%83%A8%E7%BD%B2/</link>
      <pubDate>Fri, 30 Jan 2026 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/cdh6.3.2%E9%9B%86%E7%BE%A4%E9%83%A8%E7%BD%B2/</guid>
      <description>&lt;p&gt;使用ansible做自动化部署&lt;/p&gt;
&lt;h1 id=&#34;cdh-集群安装指南&#34;&gt;CDH 集群安装指南&lt;/h1&gt;
&lt;h2 id=&#34;环境准备&#34;&gt;环境准备&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;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;NFS 服务器&lt;/td&gt;
          &lt;td&gt;xxx.xxx.xxx.xxx:/nfs/share&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Inventory&lt;/td&gt;
          &lt;td&gt;inventory/cdh-init.ini&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id=&#34;安装步骤&#34;&gt;安装步骤&lt;/h2&gt;
&lt;h3 id=&#34;步骤-1配置-etchosts-和挂载-nfs&#34;&gt;步骤 1：配置 /etc/hosts 和挂载 NFS&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ansible-playbook cdh-hosts-nfs.yml -i inventory/cdh-init.ini
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;步骤-2系统初始化&#34;&gt;步骤 2：系统初始化&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ansible-playbook cdh-init-raw.yaml -i inventory/cdh-init.ini
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id=&#34;验证&#34;&gt;验证&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 验证 NFS 挂载&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ansible cdh_all -i inventory/cdh-init.ini -m shell -a &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ls /mnt&amp;#34;&lt;/span&gt; -b
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 验证 Java&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ansible cdh_all -i inventory/cdh-init.ini -m shell -a &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;java -version&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 验证 SELinux&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ansible cdh_all -i inventory/cdh-init.ini -m shell -a &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;sestatus&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 验证 haveged&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ansible cdh_all -i inventory/cdh-init.ini -m shell -a &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;systemctl status haveged&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id=&#34;安装介质目录&#34;&gt;安装介质目录&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/mnt/
├── cdh/                    # CDH Parcel
├── ClouderaManager/        # CM 6.3.1
└── mysql/                  # MySQL 5.7 RPM
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>万历十五年</title>
      <link>https://leochu.work/blog/reading/%E4%B8%87%E5%8E%86%E5%8D%81%E4%BA%94%E5%B9%B4/</link>
      <pubDate>Mon, 12 Jan 2026 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/reading/%E4%B8%87%E5%8E%86%E5%8D%81%E4%BA%94%E5%B9%B4/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;黄仁宇《万历十五年》。核心观点：历史的转折往往不体现在戏剧性大事件中，而体现在制度内部长期积累的失衡。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;核心观点&#34;&gt;核心观点&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;看似平静的一年，往往隐藏着深层结构问题。&lt;/strong&gt; 万历十五年本身没有惊天动地的大事，但正因为如此，它更能显出帝国运转逻辑的疲态。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;个人悲剧常常是制度问题的投影。&lt;/strong&gt; 张居正、申时行、海瑞、戚继光、李贽，这些人物的命运并不只是性格故事，而是制度张力作用到个人身上的结果。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;道德化治理会掩盖技术性治理的缺失。&lt;/strong&gt; 一个系统如果只能不断诉诸名分、道德和姿态，而缺乏可计算、可执行、可调整的治理能力，迟早会陷入僵局。&lt;/p&gt;
&lt;h2 id=&#34;印象较深的部分&#34;&gt;印象较深的部分&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;帝国并不是突然崩坏的。&lt;/strong&gt; 它往往是在表面秩序仍然存在的时候，内部弹性已经一点点耗尽。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;历史里最难修复的不是一次错误，而是长期没有被正视的结构性问题。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;读后感&#34;&gt;读后感&lt;/h2&gt;
&lt;p&gt;很多表面上的人物冲突，放大看，其实都是制度问题在借人发声。&lt;/p&gt;
&lt;p&gt;把它放到现实里对照着看，会更有感觉，因为很多组织衰败的逻辑其实并没变。&lt;/p&gt;</description>
    </item>
    <item>
      <title>精益创业</title>
      <link>https://leochu.work/blog/reading/%E7%B2%BE%E7%9B%8A%E5%88%9B%E4%B8%9A/</link>
      <pubDate>Sun, 09 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/reading/%E7%B2%BE%E7%9B%8A%E5%88%9B%E4%B8%9A/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Eric Ries《精益创业》。核心观点：创业不是把想法尽快做大，而是用最小成本持续验证“哪些假设成立”。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;核心观点&#34;&gt;核心观点&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;创业的核心单位不是产品，而是学习。&lt;/strong&gt; 如果一个团队发布了很多功能，却没有获得更清楚的用户认知，本质上并没有前进。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MVP 的重点是验证，不是简陋。&lt;/strong&gt; 它的价值在于用最小代价测试关键假设，而不是随便做个半成品糊出去。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;增长必须建立在可重复的因果关系上。&lt;/strong&gt; 偶然增长不等于找到模式，真正有价值的是知道“为什么用户会留下来”。&lt;/p&gt;
&lt;h2 id=&#34;印象较深的部分&#34;&gt;印象较深的部分&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;很多团队失败不是因为不努力，而是一直在高效地做错事。&lt;/strong&gt; 这句话几乎适用于所有产品开发。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;转向不是失败，而是认知更新。&lt;/strong&gt; 当关键假设被验证为错误时，继续硬推才是真正的浪费。&lt;/p&gt;
&lt;h2 id=&#34;读后感&#34;&gt;读后感&lt;/h2&gt;
&lt;p&gt;这本书最好的地方，是它把创业从激情叙事拉回到验证逻辑。创业不是证明自己有多投入，而是在不断回答：这个问题到底存不存在，这个解法到底成不成立。&lt;/p&gt;
&lt;p&gt;不只是创业者，做产品的人读这本书也很合适。&lt;/p&gt;</description>
    </item>
    <item>
      <title>男人来自火星，女人来自金星</title>
      <link>https://leochu.work/blog/reading/%E7%94%B7%E4%BA%BA%E6%9D%A5%E8%87%AA%E7%81%AB%E6%98%9F%E5%A5%B3%E4%BA%BA%E6%9D%A5%E8%87%AA%E9%87%91%E6%98%9F/</link>
      <pubDate>Mon, 11 Aug 2025 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/reading/%E7%94%B7%E4%BA%BA%E6%9D%A5%E8%87%AA%E7%81%AB%E6%98%9F%E5%A5%B3%E4%BA%BA%E6%9D%A5%E8%87%AA%E9%87%91%E6%98%9F/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;约翰·格雷《男人来自火星，女人来自金星》。核心观点：很多两性冲突不是恶意，而是沟通语言和情感需求错位导致的误读。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;核心观点&#34;&gt;核心观点&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;很多争执并不是立场冲突，而是回应方式不对。&lt;/strong&gt; 一方在表达情绪时，希望先被理解；另一方却急着给建议、讲道理、解决问题。结果问题还没处理，情绪先被放大了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;男性和女性在压力下常见的反应不同。&lt;/strong&gt; 书里用“洞穴”和“倾诉”来做比喻：有的人会先退回自己的空间整理情绪，有的人则会通过表达来获得安慰和连接。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;爱意是否被感受到，取决于是否击中对方在意的点。&lt;/strong&gt; 你以为自己在付出，对方却可能没有接收到，因为形式不对、时机不对、语气也不对。&lt;/p&gt;
&lt;h2 id=&#34;对我有帮助的提醒&#34;&gt;对我有帮助的提醒&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;先共情，再建议。&lt;/strong&gt; 别急着修理问题，先让对方感觉自己被听见。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;不要把差异自动解释成不在乎。&lt;/strong&gt; 很多时候对方不是冷漠，而是处理情绪的方式跟自己不一样。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;关系里需要翻译能力。&lt;/strong&gt; 同一句话，在不同的人耳朵里，可能完全不是一个意思。愿意多解释一步，很多误会根本不会扩大。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;不要在错误时机沟通。&lt;/strong&gt; 一方需要空间时被追问，一方需要回应时被回避，都会让原本不大的问题迅速升级。&lt;/p&gt;
&lt;h2 id=&#34;读后感&#34;&gt;读后感&lt;/h2&gt;
&lt;p&gt;这本书有时代背景，里面有些表达今天看会显得比较类型化，但它提醒了一件很实用的事：亲密关系里，“你到底想表达什么”和“对方实际听到了什么”经常不是一回事。&lt;/p&gt;
&lt;p&gt;如果把它当成一套绝对性别规则，价值会有限；但如果把它当成一本关于差异化沟通的入门书，反而很有启发。它提供的不是结论，而是一个解释框架：很多矛盾不是谁对谁错，而是两套系统在错位运行。理解这一点，关系至少不会越走越窄。&lt;/p&gt;</description>
    </item>
    <item>
      <title>凤凰架构</title>
      <link>https://leochu.work/blog/reading/%E5%87%A4%E5%87%B0%E6%9E%B6%E6%9E%84/</link>
      <pubDate>Sun, 03 Aug 2025 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/reading/%E5%87%A4%E5%87%B0%E6%9E%B6%E6%9E%84/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;周志明《凤凰架构》。核心观点：架构不是炫技，不是堆名词，而是在约束条件下持续支持业务演进的系统设计。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;核心观点&#34;&gt;核心观点&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;架构首先服务于演进。&lt;/strong&gt; 一个系统最重要的能力，不是初版多优雅，而是变化来临时能否低成本调整。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;分布式不是目标，只是代价高昂的手段。&lt;/strong&gt; 很多问题在单体阶段并不存在，一旦走向分布式，复杂性、调用链、事务一致性、运维成本都会急剧上升。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;架构决策必须对应具体问题。&lt;/strong&gt; 如果没有明确的性能瓶颈、组织边界或交付约束，很多“先进架构”都只是过度设计。&lt;/p&gt;
&lt;h2 id=&#34;印象较深的部分&#34;&gt;印象较深的部分&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;技术选型背后总有交换。&lt;/strong&gt; 性能、可维护性、可扩展性、团队认知成本，永远不可能同时最优。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;架构能力的一部分是克制。&lt;/strong&gt; 什么时候不拆、什么时候不分布式、什么时候保留简单方案，往往比“会多少框架”更重要。&lt;/p&gt;
&lt;h2 id=&#34;读后感&#34;&gt;读后感&lt;/h2&gt;
&lt;p&gt;这本书好在它不太谈抽象的“架构之美”，而是不断把问题拉回现实：业务规模、团队能力、系统约束、演进成本。&lt;/p&gt;
&lt;p&gt;这本书最后落下来的判断很明确：好的架构师不只是会设计复杂系统，更重要的是知道复杂性应该从哪里开始，又该在哪停下来。&lt;/p&gt;</description>
    </item>
    <item>
      <title>优势谈判</title>
      <link>https://leochu.work/blog/reading/%E4%BC%98%E5%8A%BF%E8%B0%88%E5%88%A4/</link>
      <pubDate>Sat, 19 Jul 2025 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/reading/%E4%BC%98%E5%8A%BF%E8%B0%88%E5%88%A4/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;罗杰·道森《优势谈判》。核心观点：谈判不是零和博弈，而是让双方都觉得自己赢了的艺术。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;核心原则&#34;&gt;核心原则&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;永远不要接受第一次报价。&lt;/strong&gt; 即使条件很好，接受也会让对方后悔——他们会觉得本可以要得更少。让对方经过一番拉锯，才能真正感到满足。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;开价要高于预期。&lt;/strong&gt; 为自己留出让步空间。让步本身就是一种礼物，能让对方感到赢了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;让步要递减，不要等额。&lt;/strong&gt; 每次让步幅度依次缩小，暗示已经接近底线。等额让步反而会让对方期待下一次同样幅度的让步。&lt;/p&gt;
&lt;h2 id=&#34;常用战术&#34;&gt;常用战术&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;退缩（Flinch）&lt;/strong&gt;：对报价表现出明显的惊讶，无论心里怎么想。沉默和惊讶会让对方主动补充解释或降价。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;不情愿的卖家/买家&lt;/strong&gt;：在开始谈判前表现出勉为其难，压低对方的期望值，同时给自己争取更大的空间。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;更高权威&lt;/strong&gt;：告知对方需要请示上级，为自己保留退路，避免当场被逼表态。这不是谎言，是谈判工具。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;逐步蚕食（Nibbling）&lt;/strong&gt;：在达成主要协议后，再追加小要求。此时对方已经投入，更难拒绝。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;好警察/坏警察&lt;/strong&gt;：多人谈判时分工，一人强硬，一人温和，引导对方向温和一方妥协。&lt;/p&gt;
&lt;h2 id=&#34;读后感&#34;&gt;读后感&lt;/h2&gt;
&lt;p&gt;技巧本身不是重点，理解背后的心理才是。谈判双方都需要一个&amp;quot;我赢了&amp;quot;的感受，好的谈判者的工作就是在达成目标的同时，帮对方也构建这个感受。&lt;/p&gt;</description>
    </item>
    <item>
      <title>卓有成效的管理者</title>
      <link>https://leochu.work/blog/reading/%E5%8D%93%E6%9C%89%E6%88%90%E6%95%88%E7%9A%84%E7%AE%A1%E7%90%86%E8%80%85/</link>
      <pubDate>Mon, 14 Apr 2025 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/reading/%E5%8D%93%E6%9C%89%E6%88%90%E6%95%88%E7%9A%84%E7%AE%A1%E7%90%86%E8%80%85/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;彼得·德鲁克《卓有成效的管理者》。核心观点：管理者的有效性不是天赋，而是一套可以训练的工作习惯。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;核心观点&#34;&gt;核心观点&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;先管理时间。&lt;/strong&gt; 很多管理失效，本质上不是能力不足，而是时间被切碎到无法做真正重要的事。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;重视贡献而不是忙碌。&lt;/strong&gt; 有效管理者会不断问：我这项工作最终对组织产生了什么结果，而不是我今天看起来做了多少事。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;用人要看长处。&lt;/strong&gt; 管理的任务不是修理人的短板，而是把不同人的强项放到能产生效果的位置上。&lt;/p&gt;
&lt;h2 id=&#34;印象较深的部分&#34;&gt;印象较深的部分&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;决策不是越多越好，而是少而关键。&lt;/strong&gt; 真正重要的决策不会天天发生，关键在于识别哪些问题值得上升到决策层面。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;管理不是控制细节，而是让系统产出结果。&lt;/strong&gt; 一个人如果永远沉迷于亲自处理所有问题，通常意味着管理结构出了问题。&lt;/p&gt;
&lt;h2 id=&#34;读后感&#34;&gt;读后感&lt;/h2&gt;
&lt;p&gt;很多问题最后都会落回管理者自己身上：时间是不是被切碎了，事情是不是做了很多却没结果，管理是不是变成了盯细节。&lt;/p&gt;
&lt;p&gt;我读完最大的感受是，有效性不是更努力，而是先分清什么值得投入，什么只是看起来忙。&lt;/p&gt;</description>
    </item>
    <item>
      <title>JVM调优注意事项</title>
      <link>https://leochu.work/blog/tech/java/jvm%E8%B0%83%E4%BC%98%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9/</link>
      <pubDate>Sat, 12 Apr 2025 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/java/jvm%E8%B0%83%E4%BC%98%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9/</guid>
      <description>&lt;p&gt;·Xmx不要超过机器内存的50%，留下些内存供VM堆外内存和操作系统使用。
·并且Xm不要超过32G。建议最大配置为30G。接近32G,JVM会启用压缩对象指针的功能，导致
性能下降。常见es集群。具体可以参考：&lt;a href=&#34;https://www.elastic.co/cn/blog/a-heap-of-trouble&#34;&gt;A Heap of Trouble: Managing Elasticsearch&amp;rsquo;s Managed Heap | Elastic Blog&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>jdk8和jdk8u有什么区别</title>
      <link>https://leochu.work/blog/tech/java/jdk8%E5%92%8Cjdk8u%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB/</link>
      <pubDate>Sat, 29 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/java/jdk8%E5%92%8Cjdk8u%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB/</guid>
      <description>&lt;p&gt;JDK 8 代表的是一个大版本的更新，你可以理解成定义好了框架和实现&lt;/p&gt;
&lt;p&gt;JDK 8u代表的是基于JDK 8的后续小版本的迭代，里面不会有 JDK 8 标准之外的内容，只会包含一些安全性，性能等方面的修改，例如某个Class的实现优化&lt;/p&gt;
&lt;h3 id=&#34;观点一&#34;&gt;观点一&lt;/h3&gt;
&lt;p&gt;一般来说，建议选用大版本下面最新的u版本，比如你要选择 JDK 8 ，那么就选择 JDK 8u281，这个是目前8这个大版本的最新版本，原因是里面会修复和优化前序版本的一些问题&lt;/p&gt;
&lt;h3 id=&#34;观点二&#34;&gt;观点二&lt;/h3&gt;
&lt;p&gt;正常来说，应该使用OpenJDK8。&lt;/p&gt;
&lt;p&gt;OpenJDK8u是一些后期维护，一些特性并不是想要的。&lt;/p&gt;
&lt;h3 id=&#34;观点三&#34;&gt;观点三&lt;/h3&gt;
&lt;p&gt;对于jdk8u&lt;/p&gt;
&lt;p&gt;这个最新的免费版本号，其实包括了两个，8u201和8u202，这个就是JDK版本号的命名问题了。从2014年10月发布Java SE 7 Update 71(Java SE 7u71)开始，Oracle在发布Oracle JDK关键补丁更新(CPUs：Critical Patch Updates)的同时一般会发布相应的补丁集更新(PSUs：Patch Set Updates)。其中Oracle JDK关键补丁更新(CPUs)包含安全漏洞修复和重要漏洞修复，Oracle强烈建议所有Oracle JDK用户及时升级到最新的CPU版本，Oracle JDK 关键补丁更新(CPUs)版本号采用奇数编号。Oracle JDK补丁集更新(PSUs)包含相应CPUs中的所有修复以及其他非重要修复，仅当受到Oracle JDK关键补丁更新(CPUs)版本之外的其他漏洞的影响时才应当使用相应的补丁集更新 (PSUs)，Oracle JDK补丁集更新(PSUs)版本号采用偶数编号。因此，一般情况下我们只要下载奇数编号的最新版本更新就行了。&lt;/p&gt;
&lt;p&gt;简单来讲，Oracle将奇数版本作为BUG修正并全部通过检验的版本，Oracle官方建议用在生产环境最好使用这个版本。Oracle会在奇数版本之后同时发布一个偶数版本，偶数版本包含了奇数版本所有的内容，以及未被验证的BUG修复，Oracle官方建议，除非你受到未验证BUG影响，急需BUG修复才使用这个版本。因此，8u201是CPUs，关键补丁更新。8u202是PSUs，补丁集更新，推荐下载8u201。&lt;/p&gt;</description>
    </item>
    <item>
      <title>亲密关系</title>
      <link>https://leochu.work/blog/reading/%E4%BA%B2%E5%AF%86%E5%85%B3%E7%B3%BB/</link>
      <pubDate>Sun, 16 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/reading/%E4%BA%B2%E5%AF%86%E5%85%B3%E7%B3%BB/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;罗兰·米勒《亲密关系》。核心观点：好的关系不是“找到对的人”就自动成立，而是理解吸引、依恋、沟通与冲突如何共同塑造一段关系。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;核心观点&#34;&gt;核心观点&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;关系质量取决于互动是否长期稳定、可预期。&lt;/strong&gt; 我们常常不是在和真实的人相处，而是在和自己脑中的“理想伴侣模板”相处。期待越不切实际，越容易把普通摩擦解读成严重问题。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;亲密感来自持续的自我暴露。&lt;/strong&gt; 关系变深，不是因为一次惊天动地的表达，而是因为双方愿意不断交换真实的信息、情绪和脆弱。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;依恋模式会影响相处方式。&lt;/strong&gt; 安全型更容易建立稳定联结；焦虑型更容易反复确认爱；回避型则会在靠近时本能撤退。很多矛盾，不是因为不爱，而是因为应对亲密的方式不同。&lt;/p&gt;
&lt;h2 id=&#34;印象较深的部分&#34;&gt;印象较深的部分&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;吸引不只是感觉问题。&lt;/strong&gt; 熟悉、相似、接近、回应感，这些都比“命中注定”更能解释一段关系为什么会开始。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;满意度来自比较。&lt;/strong&gt; 人会用“我本来能得到什么”来衡量当前关系，所以幸福感并不只来自伴侣本身，也来自自己的参照系。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;回应感比付出总量更重要。&lt;/strong&gt; 不是做了多少，而是对方是否感到被理解、被在意。很多冲突，本质上都是回应缺失。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;冲突不可避免，但处理方式有高下。&lt;/strong&gt; 逃避、指责、翻旧账都会消耗关系；能把问题和人格分开讨论，关系才有修复空间。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;归因方式会持续影响关系温度。&lt;/strong&gt; 对伴侣更容易做负面归因，对自己则更容易找情境理由；这种偏差会一点点侵蚀善意。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;回应循环会把小问题放大成结构性问题。&lt;/strong&gt; 一方冷淡，另一方就会加码确认；加码又会让前者更想后退，最后形成“越追越逃、越逃越追”的负反馈。&lt;/p&gt;
&lt;h2 id=&#34;读后感&#34;&gt;读后感&lt;/h2&gt;
&lt;p&gt;这本书最有价值的地方，是把很多原本被浪漫化的东西重新放回现实。爱情并不是纯凭运气，也不是只靠感觉维持。很多我们以为是“缘分不好”的问题，其实是认知偏差、沟通习惯、依恋模式和互动结构共同作用的结果。&lt;/p&gt;
&lt;p&gt;成熟的亲密关系，不是从不受伤，而是双方都愿意学习如何更好地靠近彼此，同时保留边界，修正误解，维持稳定回应。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Java虚拟机栈</title>
      <link>https://leochu.work/blog/tech/java/java%E8%99%9A%E6%8B%9F%E6%9C%BA%E6%A0%88/</link>
      <pubDate>Sat, 15 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/java/java%E8%99%9A%E6%8B%9F%E6%9C%BA%E6%A0%88/</guid>
      <description>&lt;p&gt;与程序计数器一样，Java虚拟机栈（Java Virtual Machine Stack）也是线程私有的，它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的线程内存模型：每个方法被执行的时候，Java虚拟机都会同步创建一个栈帧（Stack Frame）用于存储&lt;a href=&#34;https://leochu.work/blog/tech/java/%E5%B1%80%E9%83%A8%E5%8F%98%E9%87%8F%E8%A1%A8/&#34;&gt;局部变量表&lt;/a&gt;、操作数栈、动态连接、方法出口等信息。每一个方法被调用直至执行完毕的过程，就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。&lt;/p&gt;
&lt;p&gt;经常有人把Java内存区域笼统地划分为堆内存（Heap）和栈内存（Stack），这种划分方式直接继承自传统的C、C++程序的内存布局结构，在Java语言里就显得有些粗糙了，实际的内存区域划分要比这更复杂。不过这种划分方式的流行也间接说明了程序员最关注的、与对象内存分配关系最密切的区域是“堆”和“栈”两块。其中，“堆”在稍后笔者会专门讲述，而“栈”通常就是指这里讲的虚拟机栈，或者更多的情况下只是指虚拟机栈中局部变量表部分。&lt;/p&gt;
&lt;p&gt;在《Java虚拟机规范》中，对这个内存区域规定了两类异常状况：如果线程请求的栈深度大于虚拟机所允许的深度，将抛出StackOverflowError异常；如果Java虚拟机栈容量可以动态扩展，当栈扩展时无法申请到足够的内存会抛出OutOfMemoryError异常。&lt;/p&gt;</description>
    </item>
    <item>
      <title>java代码的运行</title>
      <link>https://leochu.work/blog/tech/java/java%E4%BB%A3%E7%A0%81%E7%9A%84%E8%BF%90%E8%A1%8C/</link>
      <pubDate>Sat, 01 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/java/java%E4%BB%A3%E7%A0%81%E7%9A%84%E8%BF%90%E8%A1%8C/</guid>
      <description>&lt;h3 id=&#34;java-代码如何运行&#34;&gt;Java 代码如何运行&lt;/h3&gt;
&lt;p&gt;我们写的 Java 代码是高级语言，机器肯定是读不懂的。所以我们需要将它转换成机器能读懂的机器语言 (机器码)。 转换工作主要分为以下几个步骤：&lt;/p&gt;
&lt;h4 id=&#34;前端编译器&#34;&gt;前端编译器&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;javac&lt;/strong&gt; 就是前端编译器，可以将 java 文件编译成字节码组成的 class 文件。 java 代码如下：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Info&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;(String&lt;span style=&#34;color:#f92672&#34;&gt;[]&lt;/span&gt; args) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; a &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 1;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        System.&lt;span style=&#34;color:#a6e22e&#34;&gt;out&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;println&lt;/span&gt;(a);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;复制代码
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;执行 &lt;strong&gt;javac Info.java&lt;/strong&gt; 生成 Info.class 文件, 再使用 &lt;strong&gt;javap -c Info.class 来&lt;/strong&gt;查看其中的字节码。&lt;/p&gt;
&lt;p&gt;class 中字节码内容如下：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20230331151428.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230331151428.png&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;解释器和即时编译器&#34;&gt;解释器和即时编译器&lt;/h4&gt;
&lt;p&gt;我们通过 javac 将 java 文件编译成 class 文件，当 jvm 启动加载 class，需要逐条执行字节码指令来完成程序功能。但是程序的执行还是得在机器上，但是机器是不认识字节码的，所以我们需要将字节码转换成机器码，这样才能让机器执行程序。 &lt;em&gt;什么是机器码？&lt;/em&gt; 机器码就是用二进制代码表示的计算机能直接识别和执行的一种机器指令的集合。 而解释器和即时编译器 (Just In Time Compiler，JIT) 就是 JVM 中将字节码转化为机器码的工具。&lt;/p&gt;
&lt;h5 id=&#34;解释器&#34;&gt;解释器&lt;/h5&gt;
&lt;p&gt;解释器是一行一行地将字节码解析成机器码，解释到哪就执行到哪，狭义地说，就是 for 循环 100 次，你就要将循环体中的代码逐行解释执行 100 次。当程序需要迅速启动和执行时，解释器可以首先发挥作用，省去编译的时间，立即执行。&lt;/p&gt;</description>
    </item>
    <item>
      <title>GC Roots</title>
      <link>https://leochu.work/blog/tech/java/gc-roots/</link>
      <pubDate>Sat, 15 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/java/gc-roots/</guid>
      <description>&lt;p&gt;·在虚拟机栈（栈帧中的本地变量表）中引用的对象，譬如各个线程被调用的方法堆栈中使用到的参数、局部变量、临时变量等。&lt;/p&gt;
&lt;p&gt;·在方法区中类静态属性引用的对象，譬如Java类的引用类型静态变量。&lt;/p&gt;
&lt;p&gt;·在方法区中常量引用的对象，譬如字符串常量池（String Table）里的引用。&lt;/p&gt;
&lt;p&gt;·在本地方法栈中JNI（即通常所说的Native方法）引用的对象。&lt;/p&gt;
&lt;p&gt;·Java虚拟机内部的引用，如基本数据类型对应的Class对象，一些常驻的异常对象（比如NullPointExcepiton、OutOfMemoryError）等，还有系统类加载器。&lt;/p&gt;
&lt;p&gt;·所有被同步锁（synchronized关键字）持有的对象。&lt;/p&gt;
&lt;p&gt;·反映Java虚拟机内部情况的JMXBean、JVMTI中注册的回调、本地代码缓存等。&lt;/p&gt;
&lt;p&gt;除了这些固定的GC Roots集合以外，根据用户所选用的垃圾收集器以及当前回收的内存区域不同，还可以有其他对象“临时性”地加入，共同构成完整GC Roots集合。譬如后文将会提到的分代收集和局部回收（Partial GC），如果只针对Java堆中某一块区域发起垃圾收集时（如最典型的只针对新生代的垃圾收集），必须考虑到内存区域是虚拟机自己的实现细节（在用户视角里任何内存区域都是不可见的），更不是孤立封闭的，所以某个区域里的对象完全有可能被位于堆中其他区域的对象所引用，这时候就需要将这些关联区域的对象也一并加入GC Roots集合中去，才能保证可达性分析的正确性。&lt;/p&gt;
&lt;p&gt;目前最新的几款垃圾收集器 无一例外都具备了局部回收的特征，为了避免GC Roots包含过多对象而过度膨胀，它们在实现上也做出了各种优化处理。&lt;/p&gt;</description>
    </item>
    <item>
      <title>洞穴时间</title>
      <link>https://leochu.work/blog/thoughts/%E6%B4%9E%E7%A9%B4%E6%97%B6%E9%97%B4/</link>
      <pubDate>Sat, 08 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/thoughts/%E6%B4%9E%E7%A9%B4%E6%97%B6%E9%97%B4/</guid>
      <description>&lt;p&gt;有女生发帖：男朋友把她哄睡后，会打游戏到很晚来释放压力。她想知道，这种行为该怎么理解&lt;/p&gt;
&lt;p&gt;我试着把这件事往更严重的方向去理解。&lt;/p&gt;
&lt;p&gt;这是可能是她完全没有get到的一个关系中的巨大失败。&lt;/p&gt;
&lt;p&gt;她在对方的世界里，变成了像通勤、打卡、坐班那样的消耗，像擦屁股、撕逼那样的麻烦，像给父母报喜不报忧、明明在摸鱼却还要在同事面前演努力那样的表演——一件恼人心神、不搞定就不会自己消停、不处理就无法安生的麻烦本身。&lt;/p&gt;
&lt;p&gt;她把自己活成了一个关系中的被应付，被处理，被物化的对象。对方在她面前，深感压力，相当抵触，至少是回避、躲逃、推迟、早退，任何无厘头的理由都可以拿出来，换取片刻的安宁。极其抗拒与她的长时间物理绑定，因为物理绑定中的她，并不消停，一直试图推行本不可能的精神世界的强行交融。&lt;/p&gt;
&lt;p&gt;他们看似肉体日日共处一室，卧榻之侧香甜酣睡，实则精神深处激烈排异。&lt;/p&gt;
&lt;p&gt;把她哄睡了，自己好独处一下，就是他的一天结束时的精神打卡。&lt;/p&gt;
&lt;p&gt;她成了他时间线上一个需要被搪塞、安抚的事项之一。&lt;/p&gt;
&lt;p&gt;而不是一个让他依恋，让他沉迷，让他感觉环境宽松，压力归零，心有联结，愿意分享和物理捆绑的爱人。&lt;/p&gt;
&lt;p&gt;她以为他终于被驯服，成功被调教，每天早请示晚汇报，提供了长久的物理陪伴和充足的情绪价值。&lt;/p&gt;
&lt;p&gt;殊不知从这个时候开始，她再也难以进入他的精神家园了。她只是他赤脚进入自己独享的精神家园之前，扔掉的鞋子，洗掉的征尘，卸载的零碎和负重罢了。&lt;/p&gt;
&lt;p&gt;所谓男人的“洞穴时间”——车里那半个小时，厕所那盏不关的灯，或者深夜独自亮起的屏幕。本质未必只是独处，更可能是一段关系已经失效的证据。&lt;/p&gt;
&lt;p&gt;长期靠洞穴时间活着，对男人来说，不是什么本能，更像是一种悲哀。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Exact VM</title>
      <link>https://leochu.work/blog/tech/java/exact-vm/</link>
      <pubDate>Sat, 01 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/java/exact-vm/</guid>
      <description>&lt;p&gt;Exact VM因它使用准确式内存管理（Exact Memory Management，也可以叫Non-Con-servative/Accurate Memory Management）而得名。&lt;/p&gt;
&lt;p&gt;准确式内存管理是指虚拟机可以知道内存中某个位置的数据具体是什么类型。&lt;/p&gt;
&lt;p&gt;譬如内存中有一个32bit的整数123456，虚拟机将有能力分辨出它到底是一个指向了123456的内存地址的引用类型还是一个数值为123456的整数，准确分辨出哪些内存是引用类型，这也是在垃圾收集时准确判断堆上的数据是否还可能被使用的前提。&lt;/p&gt;
&lt;p&gt;由于使用了准确式内存管理，Exact VM可以抛弃掉以前Classic VM基于句柄（Handle）的对象查找方式（原因是垃圾收集后对象将可能会被移动位置，如果地址为123456的对象移动到654321，在没有明确信息表明内存中哪些数据是引用类型的前提下，那虚拟机肯定是不敢把内存中所有为123456的值改成654321的，所以要使用句柄来保持引用值的稳定），这样每次定位对象都少了一次间接查找的开销，显著提升执行性能。&lt;/p&gt;</description>
    </item>
    <item>
      <title>人月传奇</title>
      <link>https://leochu.work/blog/reading/%E4%BA%BA%E6%9C%88%E4%BC%A0%E5%A5%87/</link>
      <pubDate>Wed, 22 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/reading/%E4%BA%BA%E6%9C%88%E4%BC%A0%E5%A5%87/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Frederick P. Brooks Jr.《人月传奇》。核心观点：软件项目最大的难点不是编码本身，而是复杂性、沟通成本和不可压缩的系统设计工作。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;核心观点&#34;&gt;核心观点&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;向延期项目增加人手，只会让它更晚。&lt;/strong&gt; 新人加入需要沟通、培训、同步上下文，短期内增加的是负担而不是产能。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;概念完整性比局部聪明更重要。&lt;/strong&gt; 一个系统最宝贵的是整体一致的设计语言，而不是每个模块都由最聪明的人各自发挥。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;软件开发存在本质复杂性。&lt;/strong&gt; 有些问题可以靠工具改善，但需求理解、系统边界、多人协作这些难题无法被简单消灭。&lt;/p&gt;
&lt;h2 id=&#34;印象较深的部分&#34;&gt;印象较深的部分&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;人月并不能自由替换。&lt;/strong&gt; 并不是每个任务都能线性拆分后并行推进，很多关键工作天然依赖少数人做深度思考。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;文档和接口设计是沟通成本控制器。&lt;/strong&gt; 项目一旦变大，真正稀缺的就不是“谁会写代码”，而是“谁能让协作保持有序”。&lt;/p&gt;
&lt;h2 id=&#34;读后感&#34;&gt;读后感&lt;/h2&gt;
&lt;p&gt;这本书虽然老，但读起来并不旧。今天工具多了很多，项目翻车的原因却没怎么变：目标没说清，边界没定住，沟通一乱，就开始指望“再加点人”补回来。&lt;/p&gt;
&lt;p&gt;核心是把软件工程从“多写点代码”拉回到“怎么组织人和系统一起工作”。&lt;/p&gt;</description>
    </item>
    <item>
      <title>线程不安全的simpleDateFormat</title>
      <link>https://leochu.work/blog/tech/java/%E7%BA%BF%E7%A8%8B%E4%B8%8D%E5%AE%89%E5%85%A8%E7%9A%84simpledateformat/</link>
      <pubDate>Sat, 18 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/java/%E7%BA%BF%E7%A8%8B%E4%B8%8D%E5%AE%89%E5%85%A8%E7%9A%84simpledateformat/</guid>
      <description>&lt;p&gt;&lt;img alt=&#34;Pasted image 20230420183112.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230420183112.png&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;1什么是线程不安全&#34;&gt;1.什么是线程不安全？&lt;/h2&gt;
&lt;p&gt;线程不安全也叫非线程安全，是指&lt;strong&gt;多线程执行中，程序的执行结果和预期的结果不符的情况就叫做线程不安全&lt;/strong&gt;。 ​&lt;/p&gt;
&lt;h3 id=&#34;线程不安全的代码&#34;&gt;线程不安全的代码&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;SimpleDateFormat&lt;/code&gt; 就是一个典型的线程不安全事例，接下来我们动手来实现一下。首先我们先创建 10 个线程来格式化时间，时间格式化每次传递的待格式化时间都是不同的，所以程序如果正确执行将会打印 10 个不同的值，接下来我们来看具体的代码实现：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; java.text.SimpleDateFormat;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; java.util.Date;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; java.util.concurrent.ExecutorService;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; java.util.concurrent.Executors;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;SimpleDateFormatExample&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;// 创建 SimpleDateFormat 对象&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; SimpleDateFormat simpleDateFormat &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; SimpleDateFormat(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;mm:ss&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;(String&lt;span style=&#34;color:#f92672&#34;&gt;[]&lt;/span&gt; args) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;// 创建线程池&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ExecutorService threadPool &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Executors.&lt;span style=&#34;color:#a6e22e&#34;&gt;newFixedThreadPool&lt;/span&gt;(10);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;// 执行 10 次时间格式化&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0; i &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt; 10; i&lt;span style=&#34;color:#f92672&#34;&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; finalI &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; i;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#75715e&#34;&gt;// 线程池执行任务&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            threadPool.&lt;span style=&#34;color:#a6e22e&#34;&gt;execute&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; Runnable() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#a6e22e&#34;&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;run&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#75715e&#34;&gt;// 创建时间对象&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    Date date &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; Date(finalI &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; 1000);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#75715e&#34;&gt;// 执行时间格式化并打印结果&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    System.&lt;span style=&#34;color:#a6e22e&#34;&gt;out&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;println&lt;/span&gt;(simpleDateFormat.&lt;span style=&#34;color:#a6e22e&#34;&gt;format&lt;/span&gt;(date));
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            });
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我们预期的正确结果是这样的（10 次打印的值都不同）：&lt;/p&gt;</description>
    </item>
    <item>
      <title>深入理解jvm</title>
      <link>https://leochu.work/blog/reading/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3jvm/</link>
      <pubDate>Sat, 04 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/reading/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3jvm/</guid>
      <description>&lt;h2 id=&#34;第一部分-走进java&#34;&gt;第一部分 走进java&lt;/h2&gt;
&lt;h3 id=&#34;第一章-走进java&#34;&gt;第一章 走进java&lt;/h3&gt;
&lt;h4 id=&#34;12-java技术体系&#34;&gt;1.2 java技术体系&lt;/h4&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20230331145417.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230331145417.png&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;13-java发展史&#34;&gt;1.3 java发展史&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;Jigsaw项目：虚拟机层面的模块化支持。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;DLL HELL :  &lt;a href=&#34;https://leochu.work/blog/tech/engineering/%E6%A8%A1%E5%9D%97%E5%9C%B0%E7%8B%B1/&#34;&gt;模块地狱&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h4 id=&#34;14-jvm家族&#34;&gt;1.4 jvm家族&lt;/h4&gt;
&lt;h5 id=&#34;141虚拟机始祖sun-classicexact-vm&#34;&gt;1.4.1　虚拟机始祖：Sun Classic/Exact VM&lt;/h5&gt;
&lt;p&gt;编译器/解释器/即时编译器 : &lt;a href=&#34;https://leochu.work/blog/tech/java/java%E4%BB%A3%E7%A0%81%E7%9A%84%E8%BF%90%E8%A1%8C/&#34;&gt;java代码的运行&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://leochu.work/blog/tech/java/exact-vm/&#34;&gt;Exact VM&lt;/a&gt; 使用准确式内存管理（Exact Memory Management，也可以叫Non-Con-servative/Accurate Memory Management）&lt;/p&gt;
&lt;h5 id=&#34;142武林盟主hotspot-vm&#34;&gt;1.4.2　武林盟主：HotSpot VM&lt;/h5&gt;
&lt;p&gt;HotSpot虚拟机是Sun/OracleJDK和OpenJDK中的默认Java虚拟机，也是目前使用范围最广的Java虚拟机。&lt;/p&gt;
&lt;h4 id=&#34;16实战自己编译jdk&#34;&gt;1.6　实战：自己编译JDK&lt;/h4&gt;
&lt;h5 id=&#34;161获取源码&#34;&gt;1.6.1　获取源码&lt;/h5&gt;
&lt;p&gt;&lt;a href=&#34;https://hg.openjdk.java.net/jdk/jdk12/&#34;&gt;OpenJDK 12地址&lt;/a&gt;
&lt;img alt=&#34;Pasted image 20230331162843.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230331162843.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://leochu.work/blog/tech/java/jdk8%E5%92%8Cjdk8u%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB/&#34;&gt;jdk8和jdk8u有什么区别&lt;/a&gt;?&lt;/p&gt;
&lt;h5 id=&#34;162系统需求&#34;&gt;1.6.2　系统需求&lt;/h5&gt;
&lt;p&gt;推荐linux 64位和mac os 64位&lt;/p&gt;
&lt;p&gt;查看位数命令:
&lt;code&gt;getconf LONG_BIT&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;第二部分自动内存管理&#34;&gt;第二部分　自动内存管理&lt;/h2&gt;
&lt;h3 id=&#34;第2章java内存区域与内存溢出异常&#34;&gt;第2章　Java内存区域与内存溢出异常&lt;/h3&gt;
&lt;h4 id=&#34;22运行时数据区域&#34;&gt;2.2　运行时数据区域&lt;/h4&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20230331171948.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230331171948.png&#34;&gt;&lt;/p&gt;
&lt;h5 id=&#34;221程序计数器&#34;&gt;2.2.1　程序计数器&lt;/h5&gt;
&lt;p&gt;&lt;a href=&#34;https://leochu.work/blog/tech/java/%E7%A8%8B%E5%BA%8F%E8%AE%A1%E6%95%B0%E5%99%A8/&#34;&gt;程序计数器&lt;/a&gt;（Program Counter Register）是一块较小的内存空间，它可以看作是当前线程所执行的字节码的行号指示器。&lt;/p&gt;
&lt;h5 id=&#34;222java虚拟机栈&#34;&gt;2.2.2　Java虚拟机栈&lt;/h5&gt;
&lt;p&gt;与程序计数器一样，&lt;a href=&#34;https://leochu.work/blog/tech/java/java%E8%99%9A%E6%8B%9F%E6%9C%BA%E6%A0%88/&#34;&gt;Java虚拟机栈&lt;/a&gt;（Java Virtual Machine Stack）也是线程私有的，它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的线程内存模型：每个方法被执行的时候，Java虚拟机都会同步创建一个栈帧 用于存储局部变量表、操作数栈、动态连接、方法出口等信息。每一个方法被调用直至执行完毕的过程，就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。&lt;/p&gt;</description>
    </item>
    <item>
      <title>局部变量表</title>
      <link>https://leochu.work/blog/tech/java/%E5%B1%80%E9%83%A8%E5%8F%98%E9%87%8F%E8%A1%A8/</link>
      <pubDate>Sat, 21 Dec 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/java/%E5%B1%80%E9%83%A8%E5%8F%98%E9%87%8F%E8%A1%A8/</guid>
      <description>&lt;p&gt;局部变量表存放了编译期可知的各种Java虚拟机基本数据类型（boolean、byte、char、short、int、float、long、double）、对象引用（reference类型，它并不等同于对象本身，可能是一个指向对象起始地址的引用指针，也可能是指向一个代表对象的句柄或者其他与此对象相关的位置）和returnAddress类型（指向了一条字节码指令的地址）。&lt;/p&gt;
&lt;p&gt;这些数据类型在局部变量表中的存储空间以局部变量槽（Slot）来表示，其中64位长度的long和double类型的数据会占用两个变量槽，其余的数据类型只占用一个。局部变量表所需的内存空间在编译期间完成分配，当进入一个方法时，这个方法需要在栈帧中分配多大的局部变量空间是完全确定的，在方法运行期间不会改变局部变量表的大小。请读者注意，这里说的“大小”是指变量槽的数量，虚拟机真正使用多大的内存空间（譬如按照1个变量槽占用32个比特、64个比特，或者更多）来实现一个变量槽，这是完全由具体的虚拟机实现自行决定的事情。&lt;/p&gt;</description>
    </item>
    <item>
      <title>程序计数器</title>
      <link>https://leochu.work/blog/tech/java/%E7%A8%8B%E5%BA%8F%E8%AE%A1%E6%95%B0%E5%99%A8/</link>
      <pubDate>Sat, 07 Dec 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/java/%E7%A8%8B%E5%BA%8F%E8%AE%A1%E6%95%B0%E5%99%A8/</guid>
      <description>&lt;p&gt;程序计数器（Program Counter Register）是一块较小的内存空间，它可以看作是当前线程所执行的字节码的行号指示器。在Java虚拟机的概念模型里，字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令，它是程序控制流的指示器.&lt;/p&gt;
&lt;p&gt;由于Java虚拟机的多线程是通过线程轮流切换、分配处理器执行时间的方式来实现的，在任何一个确定的时刻，一个处理器（对于多核处理器来说是一个内核）都只会执行一条线程中的指令。因此，为了线程切换后能恢复到正确的执行位置，每条线程都需要有一个独立的程序计数器，各条线程之间计数器互不影响，独立存储，我们称这类内存区域为“线程私有”的内存。&lt;/p&gt;
&lt;p&gt;如果线程正在执行的是一个Java方法，这个计数器记录的是正在执行的虚拟机字节码指令的地址；如果正在执行的是本地（Native）方法，这个计数器值则应为空（Undefined）。此内存区域是唯一一个在《Java虚拟机规范》中没有规定任何OutOfMemoryError情况的区域。&lt;/p&gt;</description>
    </item>
    <item>
      <title>spark参数num-executors未生效</title>
      <link>https://leochu.work/blog/tech/bigdata/spark%E5%8F%82%E6%95%B0num-executors%E6%9C%AA%E7%94%9F%E6%95%88/</link>
      <pubDate>Sat, 23 Nov 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/spark%E5%8F%82%E6%95%B0num-executors%E6%9C%AA%E7%94%9F%E6%95%88/</guid>
      <description>&lt;h3 id=&#34;问题&#34;&gt;问题：&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;spark-submit --master yarn --conf spark.default.parallelism&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;100&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--deploy-mode cluster --driver-memory 4G --executor-memory 4G &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--num-executors &lt;span style=&#34;color:#ae81ff&#34;&gt;40&lt;/span&gt; --executor-cores &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--conf spark.yarn.executor.memoryOverhead&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;5g &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--class com.lz.hbase.CompanyInfo /tmp/test_langzi/original-spark_hbase01-1.0-SNAPSHOT.jar
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;以上提交参数中的&amp;ndash;num-executors 40没有生效，executors 大于40并且占满yarn资源，导致后来的yarn任务阻塞&lt;/p&gt;
&lt;h3 id=&#34;原因&#34;&gt;原因：&lt;/h3&gt;
&lt;p&gt;官方参数解释&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ndash;num-executors NUM
Number of executors to launch (Default: 2).
If dynamic allocation is enabled, the initial number of executors will be at least NUM.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;当开启动态分配时，num-executors成为了最小executors 数，而cdh中spark默认开启dynamic allocation，所以当yarn队列资源空闲时，真正的excutor数会大于设置的num-executors&lt;/p&gt;
&lt;h3 id=&#34;解决方案&#34;&gt;解决方案：&lt;/h3&gt;
&lt;p&gt;提交参数添加&lt;code&gt;--conf spark.dynamicAllocation.maxExecutors=40&lt;/code&gt; 限制最大excutor数&lt;/p&gt;
&lt;h3 id=&#34;附spark提交任务模板&#34;&gt;附：spark提交任务模板&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;spark-submit --master yarn --conf spark.default.parallelism&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;100&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--conf spark.dynamicAllocation.maxExecutors&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;40&lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--deploy-mode cluster --driver-memory 4G --executor-memory 4G &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--num-executors &lt;span style=&#34;color:#ae81ff&#34;&gt;40&lt;/span&gt; --executor-cores &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--conf spark.yarn.executor.memoryOverhead&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;4G &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--class com.lz.hbase.CompanyInfo /tmp/test_langzi/original-spark_hbase01-1.0-SNAPSHOT.jar
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>maven打包去除dependency-reduced-pom.xml文件</title>
      <link>https://leochu.work/blog/tech/bigdata/maven%E6%89%93%E5%8C%85%E5%8E%BB%E9%99%A4dependency-reduced-pom.xml%E6%96%87%E4%BB%B6/</link>
      <pubDate>Sat, 09 Nov 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/maven%E6%89%93%E5%8C%85%E5%8E%BB%E9%99%A4dependency-reduced-pom.xml%E6%96%87%E4%BB%B6/</guid>
      <description>&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;标签&lt;/th&gt;
          &lt;th&gt;#maven&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;场景&lt;/td&gt;
          &lt;td&gt;工作&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;时间&lt;/td&gt;
          &lt;td&gt;2023年2月14日17:58:09&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;一问题描述&#34;&gt;一、问题描述&lt;/h3&gt;
&lt;p&gt;每次打包的时候，项目目录会多出一个莫名的文件&lt;strong&gt;dependency-reduced-pom.xml&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;image-20230214175954392&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/image-20230214175954392.png&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;二导致原因&#34;&gt;二、导致原因&lt;/h3&gt;
&lt;p&gt;maven打包插件&lt;strong&gt;maven-shade-plugin&lt;/strong&gt;打包时自动生成，&lt;code&gt;createDependencyReducedPom&lt;/code&gt;默认为&lt;code&gt;true&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;dependency-reduced-pom.xml&lt;/strong&gt; 删除了已经在你的着色 jar 中的传递依赖项。这可以防止消费者两次拉他们，从而避免无用的重复。&lt;/p&gt;
&lt;h3 id=&#34;三解决方案&#34;&gt;三、解决方案&lt;/h3&gt;
&lt;p&gt;添加以下配置&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;createDependencyReducedPom&amp;gt;&lt;/span&gt;false&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/createDependencyReducedPom&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-shade-plugin&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.1.1&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;createDependencyReducedPom&amp;gt;&lt;/span&gt;false&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/createDependencyReducedPom&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;phase&amp;gt;&lt;/span&gt;package&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/phase&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;shade&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;artifactSet&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;excludes&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;exclude&amp;gt;&lt;/span&gt;org.slf4j:*&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/exclude&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;exclude&amp;gt;&lt;/span&gt;log4j:*&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/exclude&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;exclude&amp;gt;&lt;/span&gt;ch.qos.logback:*&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/exclude&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;exclude&amp;gt;&lt;/span&gt;com.google.code.findbugs:jsr305&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/exclude&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/excludes&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/artifactSet&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;filters&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;filter&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;!-- Do not copy the signatures in the META-INF folder.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;                        Otherwise, this might cause SecurityExceptions when using the JAR. --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;artifact&amp;gt;&lt;/span&gt;*:*&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/artifact&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;excludes&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;exclude&amp;gt;&lt;/span&gt;META-INF/*.SF&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/exclude&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;exclude&amp;gt;&lt;/span&gt;META-INF/*.DSA&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/exclude&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;exclude&amp;gt;&lt;/span&gt;META-INF/*.RSA&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/exclude&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/excludes&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/filter&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/filters&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;transformers&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;transformer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#a6e22e&#34;&gt;implementation=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;org.apache.maven.plugins.shade.resource.ManifestResourceTransformer&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;!-- Replace this with the main class of your job --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;mainClass&amp;gt;&lt;/span&gt;my.programs.main.clazz&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/mainClass&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/transformer&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;transformer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            &lt;span style=&#34;color:#a6e22e&#34;&gt;implementation=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;org.apache.maven.plugins.shade.resource.ServicesResourceTransformer&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/transformers&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/executions&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>kafka集群运行节点运行不成功</title>
      <link>https://leochu.work/blog/tech/bigdata/kafka%E9%9B%86%E7%BE%A4%E8%BF%90%E8%A1%8C%E8%8A%82%E7%82%B9%E8%BF%90%E8%A1%8C%E4%B8%8D%E6%88%90%E5%8A%9F/</link>
      <pubDate>Sat, 26 Oct 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/kafka%E9%9B%86%E7%BE%A4%E8%BF%90%E8%A1%8C%E8%8A%82%E7%82%B9%E8%BF%90%E8%A1%8C%E4%B8%8D%E6%88%90%E5%8A%9F/</guid>
      <description>&lt;h3 id=&#34;1现象&#34;&gt;1.现象&lt;/h3&gt;
&lt;p&gt;由于zookeeper挂掉，造成kafka出现：There are 60 offline partitions。
&lt;img alt=&#34;Pasted image 20230327102327.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230327102327.png&#34;&gt;
&lt;img loading=&#34;lazy&#34; src=&#34;http://pmd.71360.com/download/attachments/12159442/image2021-11-25_11-12-28.png?version=1&amp;modificationDate=1637809890000&amp;api=v2&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;2造成的原因&#34;&gt;2.造成的原因&lt;/h3&gt;
&lt;p&gt;经过排查发现，由于kafka之前Topic在zookeeper中的数据还在，再重新建立会产生冲突导致失败。&lt;/p&gt;
&lt;h3 id=&#34;3解决方案&#34;&gt;3.解决方案&lt;/h3&gt;
&lt;p&gt;进入Zookeeper中将之前的脏数据删掉再重启kafka。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#1.进入zookeeper&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sh /opt/cloudera/parcels/CDH-6.3.2-1.cdh6.3.2.p0.1605554/lib/zookeeper/bin/zkCli.sh
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#2.删除掉脏数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;deleteall /brokers/topics
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>hiveOnSpak客户端RemoteSparkDriver超时</title>
      <link>https://leochu.work/blog/tech/bigdata/hiveonspark%E5%AE%A2%E6%88%B7%E7%AB%AFremotesparkdriver%E8%B6%85%E6%97%B6/</link>
      <pubDate>Sat, 12 Oct 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/hiveonspark%E5%AE%A2%E6%88%B7%E7%AB%AFremotesparkdriver%E8%B6%85%E6%97%B6/</guid>
      <description>&lt;h2 id=&#34;1现象&#34;&gt;1.现象&lt;/h2&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20230327113600.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230327113600.png&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;2原因&#34;&gt;2.原因&lt;/h2&gt;
&lt;p&gt;集群资源使用率过高时可能会导致Hive On Spark查询失败-查询超时。&lt;/p&gt;
&lt;p&gt;从hive on spark的架构看出超时的位置：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20230327113614.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230327113614.png&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;3解决&#34;&gt;3.解决&lt;/h2&gt;
&lt;p&gt;修改以下参数，重启集群&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;### 其他可设置的参考参数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 在Hive client和远程Spark driver通信过程中，随机生成密码的比特数。最好设置成8的倍数。　&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hive.spark.client.secret.bits
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 远程Spark drive用于处理RPC事件所用的最大线程数，默认是8。　&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hive.spark.client.rpc.threads
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Hive client和远程Spark driver通信最大的消息大小（单位：byte）,默认是50MB。　&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hive.spark.client.rpc.max.size
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 远程Spark driver的通道日志级别，必须是DEBUG, ERROR, INFO, TRACE, WARN中的一个。　&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hive.spark.client.channel.log.level
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 用于身份验证的SASL机制的名称。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hive.spark.client.rpc.sasl.mechanisms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#生产集群设置的相应参数：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hive.spark.client.future.timeout&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;360s &lt;span style=&#34;color:#75715e&#34;&gt;# Hive client请求Spark driver的超时时间，如果没有指定时间单位，默认就是秒。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hive.metastore.client.socket.timeout&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;360s &lt;span style=&#34;color:#75715e&#34;&gt;# 客户端socket超时时间，默认20秒。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hive.spark.client.connect.timeout&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;360000ms &lt;span style=&#34;color:#75715e&#34;&gt;# Spark driver连接Hive client的超时时间，如果没有指定时间单位，默认就是毫秒。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hive.spark.client.server.connect.timeout&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;360000ms &lt;span style=&#34;color:#75715e&#34;&gt;# Hive client和远程Spark driver握手时的超时时间，这个会在两边都检查的，如果没有指定时间单位，默认就是毫秒。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hive.spark.job.monitor.timeout&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;180s &lt;span style=&#34;color:#75715e&#34;&gt;# Job监控获取Spark作业状态的超时时间，如果没有指定时间单位，默认就是秒。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>hdfs文件未关闭</title>
      <link>https://leochu.work/blog/tech/bigdata/hdfs%E6%96%87%E4%BB%B6%E6%9C%AA%E5%85%B3%E9%97%AD/</link>
      <pubDate>Sat, 28 Sep 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/hdfs%E6%96%87%E4%BB%B6%E6%9C%AA%E5%85%B3%E9%97%AD/</guid>
      <description>&lt;h3 id=&#34;问题描述&#34;&gt;问题描述：&lt;/h3&gt;
&lt;p&gt;使用hive load hdfs文件时报错：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-apl&#34; data-lang=&#34;apl&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;FAILED: Execution Error&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt; return code &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt; from org&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;apache&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;hadoop&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;hive&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;ql&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;exec&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;spark&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;SparkTask&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt; Spark job failed due to task failures: Cannot obtain block length for LocatedBlock&lt;span style=&#34;color:#66d9ef&#34;&gt;{&lt;/span&gt;BP&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1984322900&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;192.168.102.3&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1594185446267&lt;/span&gt;:blk_1180034904_106295094&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt; getBlockSize()&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;4179&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt; corrupt&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;false&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt; offset&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt; locs&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;[&lt;/span&gt;DatanodeInfoWithStorage&lt;span style=&#34;color:#e6db74&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;192.168.102.11&lt;/span&gt;:&lt;span style=&#34;color:#ae81ff&#34;&gt;9866&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt;DS&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;cb5a2e07&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;20e9&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;45&lt;/span&gt;fd&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;869&lt;/span&gt;b&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;d8b4ad170a4&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt;DISK&lt;span style=&#34;color:#e6db74&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt; DatanodeInfoWithStorage&lt;span style=&#34;color:#e6db74&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;192.168.102.9&lt;/span&gt;:&lt;span style=&#34;color:#ae81ff&#34;&gt;9866&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt;DS&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;74706&lt;/span&gt;bce&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;bb23&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;aaf&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;a6eb&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;ceaa9bdbf38c&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt;DISK&lt;span style=&#34;color:#e6db74&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt; DatanodeInfoWithStorage&lt;span style=&#34;color:#e6db74&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;192.168.102.5&lt;/span&gt;:&lt;span style=&#34;color:#ae81ff&#34;&gt;9866&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt;DS&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;57&lt;/span&gt;f122fb&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;b6ca&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;437&lt;/span&gt;c&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;a52e&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;f81efdd239c&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt;DISK&lt;span style=&#34;color:#e6db74&#34;&gt;]]&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;22&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;02&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;23&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt;:&lt;span style=&#34;color:#ae81ff&#34;&gt;31&lt;/span&gt;:&lt;span style=&#34;color:#ae81ff&#34;&gt;17&lt;/span&gt; ERROR ql&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;Driver: FAILED: Execution Error&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt; return code &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt; from org&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;apache&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;hadoop&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;hive&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;ql&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;exec&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;spark&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt;SparkTask&lt;span style=&#34;color:#a6e22e&#34;&gt;.&lt;/span&gt; Spark job failed due to task failures: Cannot obtain block length for LocatedBlock&lt;span style=&#34;color:#66d9ef&#34;&gt;{&lt;/span&gt;BP&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1984322900&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;192.168.102.3&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1594185446267&lt;/span&gt;:blk_1180034904_106295094&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt; getBlockSize()&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;4179&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt; corrupt&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;false&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt; offset&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;;&lt;/span&gt; locs&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;[&lt;/span&gt;DatanodeInfoWithStorage&lt;span style=&#34;color:#e6db74&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;192.168.102.11&lt;/span&gt;:&lt;span style=&#34;color:#ae81ff&#34;&gt;9866&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt;DS&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;cb5a2e07&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;20e9&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;45&lt;/span&gt;fd&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;869&lt;/span&gt;b&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;d8b4ad170a4&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt;DISK&lt;span style=&#34;color:#e6db74&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt; DatanodeInfoWithStorage&lt;span style=&#34;color:#e6db74&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;192.168.102.9&lt;/span&gt;:&lt;span style=&#34;color:#ae81ff&#34;&gt;9866&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt;DS&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;74706&lt;/span&gt;bce&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;bb23&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;aaf&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;a6eb&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;ceaa9bdbf38c&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt;DISK&lt;span style=&#34;color:#e6db74&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt; DatanodeInfoWithStorage&lt;span style=&#34;color:#e6db74&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;192.168.102.5&lt;/span&gt;:&lt;span style=&#34;color:#ae81ff&#34;&gt;9866&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt;DS&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;57&lt;/span&gt;f122fb&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;b6ca&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;437&lt;/span&gt;c&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;a52e&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;f81efdd239c&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt;DISK&lt;span style=&#34;color:#e6db74&#34;&gt;]]&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;分析问题&#34;&gt;分析问题：&lt;/h3&gt;
&lt;p&gt;可得知hdfs文件块出现异常，Cannot obtain block length for LocatedBlock，无法获取块文件长度信息&lt;/p&gt;
&lt;p&gt;猜测是因为昨日yarn重启导致hdfs文件未关闭写状态&lt;/p&gt;
&lt;h3 id=&#34;解决问题&#34;&gt;解决问题：&lt;/h3&gt;
&lt;p&gt;对hive load hdfs文件的地址执行检查命令&lt;/p&gt;</description>
    </item>
    <item>
      <title>hdfs文件块异常</title>
      <link>https://leochu.work/blog/tech/bigdata/hdfs%E6%96%87%E4%BB%B6%E5%9D%97%E5%BC%82%E5%B8%B8/</link>
      <pubDate>Sat, 14 Sep 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/hdfs%E6%96%87%E4%BB%B6%E5%9D%97%E5%BC%82%E5%B8%B8/</guid>
      <description>&lt;h3 id=&#34;问题描述&#34;&gt;问题描述：&lt;/h3&gt;
&lt;p&gt;使用hive load hdfs文件时报错：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;FAILED: Execution Error, &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; code 3 from org.&lt;span style=&#34;color:#a6e22e&#34;&gt;apache&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;hadoop&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;hive&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;ql&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;exec&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;spark&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;SparkTask&lt;/span&gt;. Spark job failed due to task failures: Cannot obtain block length &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; LocatedBlock{BP&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;1984322900&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;192.&lt;span style=&#34;color:#a6e22e&#34;&gt;168&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;102&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;3&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;1594185446267:blk1180034904106295094; getBlockSize()&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;4179; corrupt&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;; offset&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;0; locs&lt;span style=&#34;color:#f92672&#34;&gt;=[&lt;/span&gt;DatanodeInfoWithStorage&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;192.&lt;span style=&#34;color:#a6e22e&#34;&gt;168&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;102&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;11&lt;/span&gt;:9866,DS&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;cb5a2e07&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;20e9&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;45fd&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;869b&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;5d8b4ad170a4,DISK&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;, DatanodeInfoWithStorage&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;192.&lt;span style=&#34;color:#a6e22e&#34;&gt;168&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;102&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;9&lt;/span&gt;:9866,DS&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;74706bce&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;bb23&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;4aaf&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;a6eb&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;ceaa9bdbf38c,DISK&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;, DatanodeInfoWithStorage&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;192.&lt;span style=&#34;color:#a6e22e&#34;&gt;168&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;102&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;5&lt;/span&gt;:9866,DS&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;57f122fb&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;b6ca&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;437c&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;a52e&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;5f81efdd239c,DISK&lt;span style=&#34;color:#f92672&#34;&gt;]]&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; 22&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;02&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;23 16:31:17 ERROR ql.&lt;span style=&#34;color:#a6e22e&#34;&gt;Driver&lt;/span&gt;: FAILED: Execution Error, &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; code 3 from org.&lt;span style=&#34;color:#a6e22e&#34;&gt;apache&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;hadoop&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;hive&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;ql&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;exec&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;spark&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;SparkTask&lt;/span&gt;. Spark job failed due to task failures: Cannot obtain block length &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; LocatedBlock{BP&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;1984322900&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;192.&lt;span style=&#34;color:#a6e22e&#34;&gt;168&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;102&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;3&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;1594185446267:blk1180034904106295094; getBlockSize()&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;4179; corrupt&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;; offset&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;0; locs&lt;span style=&#34;color:#f92672&#34;&gt;=[&lt;/span&gt;DatanodeInfoWithStorage&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;192.&lt;span style=&#34;color:#a6e22e&#34;&gt;168&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;102&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;11&lt;/span&gt;:9866,DS&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;cb5a2e07&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;20e9&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;45fd&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;869b&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;5d8b4ad170a4,DISK&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;, DatanodeInfoWithStorage&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;192.&lt;span style=&#34;color:#a6e22e&#34;&gt;168&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;102&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;9&lt;/span&gt;:9866,DS&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;74706bce&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;bb23&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;4aaf&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;a6eb&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;ceaa9bdbf38c,DISK&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;, DatanodeInfoWithStorage&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;192.&lt;span style=&#34;color:#a6e22e&#34;&gt;168&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;102&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;5&lt;/span&gt;:9866,DS&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;57f122fb&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;b6ca&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;437c&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;a52e&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;5f81efdd239c,DISK&lt;span style=&#34;color:#f92672&#34;&gt;]]&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3&gt;&lt;/h3&gt;
&lt;h3 id=&#34;分析问题&#34;&gt;分析问题：&lt;/h3&gt;
&lt;p&gt;可得知hdfs文件块出现异常，Cannot obtain block length for LocatedBlock，无法获取块文件长度信息&lt;/p&gt;
&lt;p&gt;因为昨日CDH重启导致hdfs文件未关闭写状态&lt;/p&gt;
&lt;h3 id=&#34;解决问题&#34;&gt;解决问题：&lt;/h3&gt;
&lt;p&gt;对hive load hdfs文件的地址执行检查命令&lt;/p&gt;</description>
    </item>
    <item>
      <title>代码整洁之道</title>
      <link>https://leochu.work/blog/reading/%E4%BB%A3%E7%A0%81%E6%95%B4%E6%B4%81%E4%B9%8B%E9%81%93/</link>
      <pubDate>Sat, 07 Sep 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/reading/%E4%BB%A3%E7%A0%81%E6%95%B4%E6%B4%81%E4%B9%8B%E9%81%93/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Robert C. Martin《代码整洁之道》。核心观点：整洁代码不是美学偏好，而是长期可维护性的基础。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;核心观点&#34;&gt;核心观点&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;代码首先是写给人读的。&lt;/strong&gt; 机器最终当然会执行，但程序员大部分时间都花在理解和修改已有代码上。可读性不是附加价值，而是主价值。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;函数要短，职责要单一。&lt;/strong&gt; 一个函数一旦同时承担多层抽象、多种意图，理解成本就会迅速上升。短函数不是教条，单一意图才是关键。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;命名是第一层设计。&lt;/strong&gt; 好命名能直接省掉解释成本；坏命名会让系统像永远开着一层雾。&lt;/p&gt;
&lt;h2 id=&#34;印象较深的部分&#34;&gt;印象较深的部分&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;重复不只是代码味道，更是未来修改成本。&lt;/strong&gt; 逻辑复制一次看似省事，后面会以一致性风险的形式成倍偿还。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;错误处理和正常流程应当分离。&lt;/strong&gt; 把异常分支塞进主逻辑里，会让代码阅读路径被打断，结构也变得混浊。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;整洁不是一次性整理，而是持续的小修正。&lt;/strong&gt; 童子军军规式的“离开时让它比来时更干净一点”，比大规模重构更现实。&lt;/p&gt;
&lt;h2 id=&#34;读后感&#34;&gt;读后感&lt;/h2&gt;
&lt;p&gt;代码不会在项目后期突然变整洁，它只会在每次提交里慢慢变好，或者慢慢变烂。&lt;/p&gt;
&lt;p&gt;很多工程问题到最后都不是技术突破不了，而是前面欠下的整洁债开始一起算账。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Flume内存溢出卡死</title>
      <link>https://leochu.work/blog/tech/bigdata/flume%E5%86%85%E5%AD%98%E6%BA%A2%E5%87%BA%E5%8D%A1%E6%AD%BB/</link>
      <pubDate>Sat, 31 Aug 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/flume%E5%86%85%E5%AD%98%E6%BA%A2%E5%87%BA%E5%8D%A1%E6%AD%BB/</guid>
      <description>&lt;h3 id=&#34;问题agent启动后跑到一半报错卡死&#34;&gt;问题：agent启动后跑到一半报错卡死&lt;/h3&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20230327115742.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230327115742.png&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;解决修改flume_ng启动脚本中jvm参数&#34;&gt;解决：修改flume_ng启动脚本中jvm参数：&lt;/h3&gt;
&lt;p&gt;vi /opt/cloudera/parcels/CDH/lib/flume-ng/bin/flume-ng&lt;/p&gt;
&lt;p&gt;把 &lt;em&gt;JAVA_OPTS=&amp;quot;-Xmx20m&lt;/em&gt;&amp;quot; 改为 &lt;em&gt;JAVA_OPTS=&amp;quot;-Xmx2048m&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20230327115750.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230327115750.png&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;重启agent顺畅running&#34;&gt;重启agent，顺畅running&lt;/h3&gt;</description>
    </item>
    <item>
      <title>flume不关闭临时文件</title>
      <link>https://leochu.work/blog/tech/bigdata/flume%E4%B8%8D%E5%85%B3%E9%97%AD%E4%B8%B4%E6%97%B6%E6%96%87%E4%BB%B6/</link>
      <pubDate>Sat, 17 Aug 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/flume%E4%B8%8D%E5%85%B3%E9%97%AD%E4%B8%B4%E6%97%B6%E6%96%87%E4%BB%B6/</guid>
      <description>&lt;h4 id=&#34;问题描述flume采集到hdfs上的文件一直不关闭有tmp后缀hive读不到&#34;&gt;问题描述：flume采集到hdfs上的文件一直不关闭，有tmp后缀，hive读不到&lt;/h4&gt;
&lt;h4 id=&#34;原配置&#34;&gt;原配置：&lt;/h4&gt;
&lt;p&gt; # 当前文件写入达到该值时间后触发滚动创建新文件，单位：秒，设置为24小时防止产生小文件&lt;br&gt;
 ex_trade_agent.sinks.k1.hdfs.rollInterval = 86400&lt;br&gt;
 # 当前文件写入达到该大小后触发滚动创建新文件，单位：字节，设置为128M&lt;br&gt;
 ex_trade_agent.sinks.k1.hdfs.rollSize = 134217700&lt;br&gt;
 # 向 HDFS 写入内容时每次批量操作的 Event 数量&lt;br&gt;
 ex_trade_agent.sinks.k1.hdfs.batchSize = 2000&lt;br&gt;
 # 不根据 Event 数量来分割文件&lt;br&gt;
 ex_trade_agent.sinks.k1.hdfs.rollCount = 0&lt;/p&gt;
&lt;p&gt;可以看到只按照128m和24小时来判断是否写新文件，如果两者都不满足那就不关闭临时文件&lt;/p&gt;
&lt;h4 id=&#34;解决方案&#34;&gt;解决方案：&lt;/h4&gt;
&lt;p&gt; # 当前文件写入达到该值时间后触发滚动创建新文件，单位：秒，设置为4小时防止产生小文件&lt;br&gt;
 ex_trade_agent.sinks.k1.hdfs.rollInterval = 14400&lt;br&gt;
 # 当非活动文件超过4小时，关闭该文件&lt;br&gt;
 ex_trade_agent.sinks.k1.hdfs.idleTimeout = 14400&lt;/p&gt;</description>
    </item>
    <item>
      <title>flink虚拟内存不足</title>
      <link>https://leochu.work/blog/tech/bigdata/flink%E8%99%9A%E6%8B%9F%E5%86%85%E5%AD%98%E4%B8%8D%E8%B6%B3/</link>
      <pubDate>Sat, 03 Aug 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/flink%E8%99%9A%E6%8B%9F%E5%86%85%E5%AD%98%E4%B8%8D%E8%B6%B3/</guid>
      <description>&lt;h2 id=&#34;1现象&#34;&gt;1.现象&lt;/h2&gt;
&lt;p&gt;flink任务提交任务虚拟内存不足导致的失败&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Container &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;pid&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;3007,containerID&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;container_1599018748796_0004_01_000004&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; is  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;running 342252032B beyond the &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;VIRTUAL&amp;#39;&lt;/span&gt; memory limit. Current usage: 416.0 MB  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;of &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; GB physical memory used; 2.4 GB of 2.1 GB virtual memory used.  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Killing container.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;2原因&#34;&gt;2.原因&lt;/h2&gt;
&lt;p&gt;因为yarn强制检查虚拟内存是否符合配置导致的，当我们的服务器或者虚拟机的内存达不到配置要求，可能就会报这个错误 。&lt;/p&gt;
&lt;h2 id=&#34;3解决&#34;&gt;3.解决&lt;/h2&gt;
&lt;p&gt;修改检查虚拟内存的属性为false&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;property&amp;gt;&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;name&amp;gt;&lt;/span&gt;yarn.nodemanager.vmem-check-enabled&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;value&amp;gt;&lt;/span&gt;false&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>flink查看stdout日志</title>
      <link>https://leochu.work/blog/tech/bigdata/flink%E6%9F%A5%E7%9C%8Bstdout%E6%97%A5%E5%BF%97/</link>
      <pubDate>Sat, 20 Jul 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/flink%E6%9F%A5%E7%9C%8Bstdout%E6%97%A5%E5%BF%97/</guid>
      <description>&lt;h4 id=&#34;问题&#34;&gt;问题:&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;flink的web管理界面在日志过大时无法加载且无法下载&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/image-20230209180331732.png&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;解决&#34;&gt;解决:&lt;/h4&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/image-20230209180433316.png&#34;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;复制该任务task manager的container编号 container_e01_1675618892497_0264_01_000003&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;远程登录该task manager所在服务器&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;使用命令查询进程&lt;/strong&gt; &lt;code&gt;ps -ef | grep taskmanager | grep -v &amp;quot;bash -c&amp;quot; |grep container_e01_1675618892497_0264_01_000003&lt;/code&gt; &lt;img loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/image-20230209180903878.png&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;进入该目录&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;各文件用途&lt;/strong&gt; taskmanager.out：业务侧的输出文件，该文件中的内容一般是业务代码中，使用算子的print()方法或者使用java的System.out.print()产生的内容，与前台的taskmanager输出打印内容一致&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;taskmanager.log就是运行中的taskmanager的日志&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;taskmanager.err ：taskmanager中出错时候的异常信息&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;gc.log.x.current：taskmanager的gc日志&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    <item>
      <title>ES映射hive数据类型date无法解析</title>
      <link>https://leochu.work/blog/tech/bigdata/es%E6%98%A0%E5%B0%84hive%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8Bdate%E6%97%A0%E6%B3%95%E8%A7%A3%E6%9E%90/</link>
      <pubDate>Sat, 06 Jul 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/es%E6%98%A0%E5%B0%84hive%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8Bdate%E6%97%A0%E6%B3%95%E8%A7%A3%E6%9E%90/</guid>
      <description>&lt;h3 id=&#34;在es中数据类型为date&#34;&gt;在es中数据类型为date：&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;addTime&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;format&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;yyyy-MM-dd HH:mm:ss&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;date&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;在hive建映射表&#34;&gt;在hive建映射表&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;CREATE&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;EXTERNAL&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;TABLE&lt;/span&gt; hive_es.cty_test1(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;addTime date
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;STORED &lt;span style=&#34;color:#66d9ef&#34;&gt;BY&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;org.elasticsearch.hadoop.hive.EsStorageHandler&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;TBLPROPERTIES(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;es.resource&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;cty_test/cty_test&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;es.nodes&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;172.16.98.113,172.16.98.149,172.16.98.150,172.16.98.151,172.16.98.152&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;es.port&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;9200&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;es.mapping.names&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;addTime:addTime&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;es.date.format&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;yyyy-MM-dd HH:mm:ss&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;es.index.auto.create&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;false&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;查询报错&#34;&gt;查询报错：&lt;/h3&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20230327120417.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230327120417.png&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;更改hive表数据类型为string&#34;&gt;更改hive表数据类型为string&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;CREATE&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;EXTERNAL&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;TABLE&lt;/span&gt; hive_es.cty_test5(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;addTime string
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;STORED &lt;span style=&#34;color:#66d9ef&#34;&gt;BY&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;org.elasticsearch.hadoop.hive.EsStorageHandler&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;TBLPROPERTIES(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;es.resource&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;cty_test/cty_test&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;es.nodes&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;172.16.98.113,172.16.98.149,172.16.98.150,172.16.98.151,172.16.98.152&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;es.port&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;9200&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;es.mapping.names&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;addTime:addTime&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;es.date.format&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;yyyy-MM-dd HH:mm:ss&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;es.index.auto.create&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;false&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;查询继续报错&#34;&gt;查询继续报错：&lt;/h3&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20230327120434.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230327120434.png&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;查阅资料&#34;&gt;查阅资料：&lt;/h3&gt;
&lt;p&gt;elasticsearch-hadoop中用于将ES中的日期转换为Hive中的日期格式的类为org.elasticsearch.hadoop.hive.HiveValueReader，通过查看该类的源码，其实现的用户日期转换的方法为：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;protected&lt;/span&gt; Object &lt;span style=&#34;color:#a6e22e&#34;&gt;parseDate&lt;/span&gt;(String value, &lt;span style=&#34;color:#66d9ef&#34;&gt;boolean&lt;/span&gt; richDate) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; (richDate &lt;span style=&#34;color:#f92672&#34;&gt;?&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; TimestampWritable(&lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; Timestamp(DatatypeConverter.&lt;span style=&#34;color:#a6e22e&#34;&gt;parseDateTime&lt;/span&gt;(value).&lt;span style=&#34;color:#a6e22e&#34;&gt;getTimeInMillis&lt;/span&gt;())) : parseString(value));
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;可以看到它是通过javax.xml.bind.DatatypeConverter.parseDateTime(String)方法将对应的日期字符串转换为日期的，该方法不支持的日期字符串格式为“yyyy-MM-dd HH:mm:ss”的字符串，它支持的日期字符串的格式为“yyyy-MM-ddTHH:mm:ss”这样的。&lt;/p&gt;
&lt;h3 id=&#34;解决方案&#34;&gt;解决方案：&lt;/h3&gt;
&lt;p&gt;在建表时设置参数&amp;rsquo;es.mapping.date.rich&amp;rsquo;=&amp;lsquo;false&amp;rsquo;，然后hive字段类型设为string。&lt;/p&gt;
&lt;h3 id=&#34;官方解释&#34;&gt;官方解释：&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Whether to create a rich Date like object for Date fields in Elasticsearch or returned them as primitives (String or long). By default this is true. The actual object type is based on the library used; noteable exception being Map/Reduce which provides no built-in Date object and as such LongWritable and Text are returned regardless of this setting.&lt;/p&gt;</description>
    </item>
    <item>
      <title>dolphin踩坑</title>
      <link>https://leochu.work/blog/tech/bigdata/dolphinscheduler%E8%B8%A9%E5%9D%91/</link>
      <pubDate>Sat, 22 Jun 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/dolphinscheduler%E8%B8%A9%E5%9D%91/</guid>
      <description>&lt;ul&gt;
&lt;li&gt;一个sql节点只能写一条sql且结尾不能写分号&lt;/li&gt;
&lt;li&gt;使用sql节点时由于dolohin写了hive的预编译，某些时候变量不能正确传入，比如 location ‘xxxxx${变量名}’,在预编译过程中会直接变成 location ‘xxxxx?’
**解决方案：**把sql节点替换成shell节点用hive -e &amp;lsquo;&amp;hellip;&amp;hellip;&amp;hellip;&amp;hellip;.. location ‘xxxxx${变量名}’来实现变量传参&lt;/li&gt;
&lt;li&gt;节点开启非严格模式，从节点偶尔会失效
**解决方案：**每个需要动态分区的sql都加上设置非严格模式的前置sql&lt;/li&gt;
&lt;li&gt;sql节点无法使用hive永久注册的udf
**解决方案：**在dolphin资源中心上传udf并创建（会注册成临时udf）&lt;/li&gt;
&lt;li&gt;sql节点使用 REPLACE函数会有bug，导致任务流无法保存
**解决方案：**使用REGEXP_REPLACE函数&lt;/li&gt;
&lt;li&gt;sql节点添加扩展jar包，无法使用本地路径
**解决方案：**需要先上传jar到hdfs，然后加上hdfs://nameservice1/前缀&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    <item>
      <title>部署CDH踩坑总结</title>
      <link>https://leochu.work/blog/tech/bigdata/%E9%83%A8%E7%BD%B2cdh%E8%B8%A9%E5%9D%91%E6%80%BB%E7%BB%93/</link>
      <pubDate>Sat, 08 Jun 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/%E9%83%A8%E7%BD%B2cdh%E8%B8%A9%E5%9D%91%E6%80%BB%E7%BB%93/</guid>
      <description>&lt;p&gt;1.zookeeper刚启动时会报错，晾它两分钟会就好了&lt;/p&gt;
&lt;p&gt;2.更改或迁移服务时一定要切换到维护模式并停止当前服务！！！&lt;/p&gt;
&lt;p&gt;3.cdh01的hadoop组件起不来，原因是一些文件夹的权限问题，更改权限并且更改拥有者及组（参照其他服务器）&lt;/p&gt;
&lt;p&gt;4.内存不足主要因为NodeManager内存调的太高，调小即可（个人经验，5台机器可用内存和为30*4+20=160G，可同时对20G的数据做处理，感觉够用了）&lt;/p&gt;
&lt;p&gt;5.oozie报错：Failed to install Oozie ShareLib，这个问题是cdh6.2的通病，只要安装oozie就会 出现(无论是升级，还是新装。&lt;/p&gt;
&lt;p&gt;解决：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cd /opt/cloudera/parcels/CDH/lib/oozie/libtools&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ln -s ../../../jars/logredactor-2.0.7.jar logredactor-2.0.7.jar&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;执行完后重启oozie。&lt;/p&gt;
&lt;p&gt;6.oozie端口号11000冲突，改为11002&lt;/p&gt;
&lt;p&gt;7.从节点不要提前安装agent服务！！！直接在web界面安装！&lt;/p&gt;
&lt;p&gt;8.把CM和CDH装好后面就轻松多了&lt;/p&gt;
&lt;p&gt;9.==主机名不要出现下划线!==&lt;/p&gt;</description>
    </item>
    <item>
      <title>国王，武士，祭司，诗人</title>
      <link>https://leochu.work/blog/reading/%E5%9B%BD%E7%8E%8B%E6%AD%A6%E5%A3%AB%E7%A5%AD%E5%8F%B8%E8%AF%97%E4%BA%BA/</link>
      <pubDate>Sat, 18 May 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/reading/%E5%9B%BD%E7%8E%8B%E6%AD%A6%E5%A3%AB%E7%A5%AD%E5%8F%B8%E8%AF%97%E4%BA%BA/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;罗伯特·摩尔《国王，武士，祭司，诗人》。核心观点：成熟男性人格不是单一特质，而是四种原型之间的平衡。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;核心观点&#34;&gt;核心观点&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;国王代表秩序与祝福。&lt;/strong&gt; 健康的国王型人格会建立边界、分配资源、让周围人各得其所；失衡时则会滑向专断或软弱。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;武士代表行动与纪律。&lt;/strong&gt; 武士的价值不在攻击性，而在执行力、方向感和承担痛苦的能力。没有武士，很多判断最终都落不了地。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;祭司代表洞察与理解。&lt;/strong&gt; 他对应的是解释世界、提炼模式、理解因果的能力。这个部分越弱，人越容易陷入情绪化和短视。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;诗人代表感受与想象。&lt;/strong&gt; 诗人型让人保有柔软、审美、象征感和与内心世界的连接；但过度时也可能滑向沉溺和虚无。&lt;/p&gt;
&lt;h2 id=&#34;印象较深的部分&#34;&gt;印象较深的部分&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;很多人的问题不是没有力量，而是力量结构失衡。&lt;/strong&gt; 有人只有武士，没有国王，所以执行力强但总在打仗；有人只有祭司，没有武士，所以理解很多但始终不行动。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;成熟不是压抑某一面，而是让不同部分各归其位。&lt;/strong&gt; 这本书最有启发的一点，就是它不把“强硬”“敏感”“理性”“秩序”对立起来，而是把它们看作一整套人格结构。&lt;/p&gt;
&lt;h2 id=&#34;读后感&#34;&gt;读后感&lt;/h2&gt;
&lt;p&gt;这本书原型心理学的味道很重，不是那种拿来就能用的工具书。但它提供了一个很好用的观察框架：很多人并不是简单地“性格有问题”，而是人格结构失了衡。&lt;/p&gt;
&lt;p&gt;把它当镜子看自己，比把它当结论去套别人，要有用得多。&lt;/p&gt;</description>
    </item>
    <item>
      <title>指标字典</title>
      <link>https://leochu.work/blog/tech/bigdata/%E6%8C%87%E6%A0%87%E5%AD%97%E5%85%B8/</link>
      <pubDate>Sat, 11 May 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/%E6%8C%87%E6%A0%87%E5%AD%97%E5%85%B8/</guid>
      <description>&lt;h2 id=&#34;1指标字典&#34;&gt;&lt;strong&gt;1.指标字典&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;指标字典，是业务数据标准化的基础，目的是对指标进行统一管理，方便共享达成对业务指标的共识，并且统一修改和维护。指标字典可以更新在 Excel或者Wiki中。如果有足够多的资源，那么开发指标管理模块可以放在数据管理系统中再配合血缘关系，就可以很方便追踪数据流转了。&lt;/p&gt;
&lt;h3 id=&#34;11设计指标字典的主要目的&#34;&gt;&lt;strong&gt;1.1设计指标字典的主要目的：&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;(1)规范维度和量度命名，命名规则要尽量做到明确、通用、易懂。&lt;/p&gt;
&lt;p&gt;(2)对维度或量度统一计算口径，避免岐义。&lt;/p&gt;
&lt;p&gt;(3)涵盖尽可能多的关注的核心维度和量度，以此为基础推动数据建设，确保指标字典里覆盖的维度都可区分、指标都可统计&lt;/p&gt;
&lt;p&gt;(4)基于指标字典，将核心维度和量度注入元数据中心，接入指标提取工具，后续实现不需要写QL语句即可完成自査询及分析需求&lt;/p&gt;
&lt;p&gt;指标字典的建立，是搭建数据平台的基础。&lt;/p&gt;
&lt;h3 id=&#34;12指标量度和维度的相关概念&#34;&gt;&lt;strong&gt;1.2指标、量度和维度的相关概念&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id=&#34;121-指标&#34;&gt;&lt;strong&gt;1.2.1 指标:&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;定义：衡量目标的方法&lt;/p&gt;
&lt;p&gt;构成要素：维度+汇总方式+量度&lt;/p&gt;
&lt;p&gt;（1）维度=哪些角度去看问题&lt;/p&gt;
&lt;p&gt;（2）汇总方式=哪些方法衡量问题&lt;/p&gt;
&lt;p&gt;（3）量度=目标是什么问题&lt;/p&gt;
&lt;h4 id=&#34;122-维度&#34;&gt;&lt;strong&gt;1.2.2 维度：&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;定义：看问题的角度和方向，例如我要从年份看毛衣的销量，那么年份就是我看问题的角度&lt;/p&gt;
&lt;h4 id=&#34;123-量度&#34;&gt;&lt;strong&gt;1.2.3 量度：&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;定义：对一个物理量的测定，通常数字+计算单位表示。例如，金额，次数，率&lt;/p&gt;
&lt;h3 id=&#34;13-指标定义规范&#34;&gt;&lt;strong&gt;1.3 指标定义规范&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id=&#34;131怎么定义一个合格的指标字典需要遵守什么规范&#34;&gt;&lt;strong&gt;1.3.1怎么定义一个合格的指标字典？需要遵守什么规范？&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;一个指标一经录入，它的命名和所有下钻维度的口径都已确定(默认口径)，这称为指标的一义性。&lt;br&gt;
例如，“交易额”这个指标默认的时间口径是：支付时间，默认的城市口径是：下单所在城市等。&lt;br&gt;
如果需要按下单时间口径看订单金额，我们定义了一个新的指标“下单交易额”。一个在某些维度上口径不确定的“指标”是不能被使用的，在业务场景中是毫无意义的。&lt;/p&gt;
&lt;h4 id=&#34;132指标一般分为基础指标普通指标和计算指标三类&#34;&gt;&lt;strong&gt;1.3.2指标一般分为基础指标、普通指标和计算指标三类。&lt;/strong&gt;&lt;/h4&gt;
&lt;h5 id=&#34;1321基础指标&#34;&gt;&lt;strong&gt;1.3.2.1基础指标&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;例如，“交易额”作为一个基于单纯实体的属性的简单计算，它没有更上游的指标，即它的父指标是它自身。我们称这样的指标为基础指标。&lt;/p&gt;
&lt;h5 id=&#34;1322普通指标&#34;&gt;&lt;strong&gt;1.3.2.2.普通指标&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;所谓普通指标，即在单一父指标的基础上通过一些维度上的取值限定可以定义的指标。&lt;br&gt;
例如，对于购买中PC端首次购买用户数，限制条件为首次购买用户中下单平台＝PC。&lt;/p&gt;
&lt;h5 id=&#34;1323计算指标&#34;&gt;&lt;strong&gt;1.3.2.3.计算指标&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;可以在若干个注册指标之上通过四则运算、排序、累计或汇总定义出的指标称为计算指标。&lt;/p&gt;
&lt;h3 id=&#34;14量度和维度都考虑好了在构建一个指标字典时我们应该考虑哪些要素呢&#34;&gt;&lt;strong&gt;1.4量度和维度都考虑好了，在构建一个指标字典时我们应该考虑哪些要素呢?&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id=&#34;141指标字典要素如下&#34;&gt;&lt;strong&gt;1.4.1指标字典要素如下：&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20260323095931.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020260323095931.png&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;142通常指标字典包含指标维度和指标量度两个部分如下&#34;&gt;&lt;strong&gt;1.4.2通常指标字典包含指标维度和指标量度两个部分，如下：&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20260323095936.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020260323095936.png&#34;&gt;
&lt;img alt=&#34;Pasted image 20260323095940.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020260323095940.png&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;总结&#34;&gt;&lt;strong&gt;总结：&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;通过上面的步骤和方法，根据自身业务情况，建立一个指标字典。&lt;/p&gt;
&lt;p&gt;指标字典在建立知乎，要经过各个业务产品经理的评审，纠正错误不明或者有歧义的指标，在达成一致后，由数据产品推广，共大家参考使用。&lt;/p&gt;
&lt;p&gt;好的指标字典就像二叉树一样，从单维度，粗糙维度分析，再细拆维度。看问题需要：由大到小，由内到外。&lt;/p&gt;</description>
    </item>
    <item>
      <title>restful风格</title>
      <link>https://leochu.work/blog/tech/engineering/restful%E9%A3%8E%E6%A0%BC/</link>
      <pubDate>Sat, 13 Apr 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/restful%E9%A3%8E%E6%A0%BC/</guid>
      <description>&lt;h3 id=&#34;一什么是-rest-一种软件架构风格&#34;&gt;一、什么是 REST ？（一种软件架构风格）&lt;/h3&gt;
&lt;p&gt;缩写：REST （不是&amp;quot;rest&amp;quot;这个单词）
外文名：Representational State Transfer，简称REST。
中文名：表现层状态转移。&lt;/p&gt;
&lt;p&gt;提出时间：2000年。
属性：一种软件架构风格。（以Web为平台的。web服务的架构风格，前后端接口时候用到。）&lt;/p&gt;
&lt;p&gt;REST之所以晦涩难懂，是因为前面主语（Resource ）被去掉了。
全称是： Resource Representational State Transfer。
通俗来讲就是：资源在网络中以某种表现形式进行状态转移。&lt;/p&gt;
&lt;p&gt;分解开来讲解:
Resource：资源，即数据（这是网络的核心）；
Representational：某种表现形式，比如用JSON，XML，JPEG等；
State Transfer：状态变化。通过HTTP的动词（get查询、post新增、put修改、delete删除）实现。&lt;/p&gt;
&lt;p&gt;一句话描述 REST 实质：&lt;br&gt;
URL 中只使用名词来定位资源，用 HTTP 协议里的动词（GET、POST、PUT、DELETE）来实现资源的增删改查操作。&lt;/p&gt;
&lt;p&gt;什么意思呢？&lt;/p&gt;
&lt;p&gt;比如，我们有一个 friends 接口，对于 “朋友” 我们有增删改查四种操作，怎么定义 REST 接口？&lt;/p&gt;
&lt;p&gt;增加一个朋友，uri: generalcode.cn/v1/friends 接口类型：POST&lt;br&gt;
删除一个朋友，uri: generalcode.cn/va/friends 接口类型：DELETE（在 http 的 parameter 指定好友 id）&lt;br&gt;
修改一个朋友，uri: generalcode.cn/va/friends 接口类型：PUT（在 http 的 parameter 指定好友 id）&lt;br&gt;
查找一个朋友，uri: generalcode.cn/va/friends 接口类型：GET&lt;/p&gt;
&lt;p&gt;上面我们定义的四个接口就是符合 REST 协议的，请注意，这几个接口都没有动词，只有名词 friends，都是通过 Http 请求的接口类型来判断是什么业务操作。&lt;/p&gt;
&lt;p&gt;举个反例：
generalcode.cn/va/deleteFriends 该接口用来表示删除朋友，这就是不符合REST协议的接口。
不能用deleteFriends ，而应该就用friends + http请求的delete方式。&lt;/p&gt;</description>
    </item>
    <item>
      <title>python读文件</title>
      <link>https://leochu.work/blog/tech/python/python%E8%AF%BB%E6%96%87%E4%BB%B6/</link>
      <pubDate>Sat, 30 Mar 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/python/python%E8%AF%BB%E6%96%87%E4%BB%B6/</guid>
      <description>&lt;h2 id=&#34;1-直接打开就读&#34;&gt;1. 直接打开就读&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;with open(&amp;#39;filepath&amp;#39;,&amp;#39;r&amp;#39;) as f:
    for line in f:
        print（line）
        print(&amp;#39;一行数据&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;虽然 f 是一个文件实例，但可以通过以上方式对每一行进行循环处理了，处理时每一行是一个字符串 str, 而且这个是速度最快最简洁的方法&lt;/p&gt;
&lt;h2 id=&#34;2-用-read打开&#34;&gt;2. 用 read（）打开&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;with open(&amp;#39;filepath&amp;#39;,&amp;#39;r&amp;#39;) as f:
    ff=f.read()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这个函数把文件全部内容一次性读到一个字符串中。就是一坨的那种，如果把 ff 用循环读取的方式输出，会是一个一个字符，因为 ff 是字符串，本质上是 tuple&lt;/p&gt;
&lt;h2 id=&#34;3-用-readlines&#34;&gt;3. 用 readlines（）&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;with open(&amp;#39;filepath&amp;#39;,&amp;#39;r&amp;#39;) as f:
    lines=f.readlines()
    for line in lines:
        print(line)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这个函数将文件所用内容以行为区分读到一个列表中 ，列表中的每一个元素是一行；lines 是 list，line 是 str&lt;/p&gt;
&lt;h2 id=&#34;4-用-readline&#34;&gt;4. 用 readline()&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;with open(&amp;#39;filepath&amp;#39;,&amp;#39;r&amp;#39;) as f:
    line =f.readline()
    while line:
        print(line)
        line=f.readline()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这种方式是一行一行的读，非常的省内存，当文件巨大的情况下是有好处的&lt;/p&gt;
&lt;h2 id=&#34;注&#34;&gt;注&lt;/h2&gt;
&lt;p&gt;如果不用 with open 可以用以下代码来打开关闭文件&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;f=open(path,&amp;#39;r&amp;#39;)
f.close()
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>ORM常用操作</title>
      <link>https://leochu.work/blog/tech/python/django/orm%E5%B8%B8%E7%94%A8%E6%93%8D%E4%BD%9C/</link>
      <pubDate>Sat, 16 Mar 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/python/django/orm%E5%B8%B8%E7%94%A8%E6%93%8D%E4%BD%9C/</guid>
      <description>&lt;h1 id=&#34;orm常用操作&#34;&gt;ORM常用操作&lt;/h1&gt;
&lt;p&gt;Django开发过程中对表(model)的增删改查是最常用的功能之一，本文介绍笔者在使用model 操作过程中遇到的一些操作。&lt;/p&gt;
&lt;h1 id=&#34;model-update常规用法&#34;&gt;model update常规用法&lt;/h1&gt;
&lt;p&gt;假如我们的表结构是这样的&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;class User(models.Model):
    username = models.CharField(max_length=255, unique=True, verbose_name=&amp;#39;用户名&amp;#39;)
    is_active = models.BooleanField(default=False, verbose_name=&amp;#39;激活状态&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;那么我们修改用户名和状态可以使用如下两种方法：&lt;/p&gt;
&lt;p&gt;方法一：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;User.objects.filter(id=1).update(username=&amp;#39;nick&amp;#39;,is_active=True)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;方法二：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;_t = User.objects.get(id=1)
_t.username=&amp;#39;nick&amp;#39;
_t.is_active=True
_t.save()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;方法一适合更新一批数据，类似于mysql语句&lt;code&gt;update user set username=&#39;nick&#39; where id = 1&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;方法二适合更新一条数据，也只能更新一条数据，当只有一条数据更新时推荐使用此方法，另外此方法还有一个好处，我们接着往下看&lt;/p&gt;
&lt;h1 id=&#34;具有auto_now属性字段的更新&#34;&gt;具有auto_now属性字段的更新&lt;/h1&gt;
&lt;p&gt;我们通常会给表添加三个默认字段&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自增ID，这个django已经默认加了，就像上边的建表语句，虽然只写了username和is_active两个字段，但表建好后也会有一个默认的自增id字段&lt;/li&gt;
&lt;li&gt;创建时间，用来标识这条记录的创建时间，具有&lt;code&gt;auto_now_add&lt;/code&gt;属性，创建记录时会自动填充当前时间到此字段&lt;/li&gt;
&lt;li&gt;修改时间，用来标识这条记录最后一次的修改时间，具有&lt;code&gt;auto_now&lt;/code&gt;属性，当记录发生变化时填充当前时间到此字段&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;就像下边这样的表结构&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;class User(models.Model):
    create_time = models.DateTimeField(auto_now_add=True, verbose_name=&amp;#39;创建时间&amp;#39;)
    update_time = models.DateTimeField(auto_now=True, verbose_name=&amp;#39;更新时间&amp;#39;)
    username = models.CharField(max_length=255, unique=True, verbose_name=&amp;#39;用户名&amp;#39;)
    is_active = models.BooleanField(default=False, verbose_name=&amp;#39;激活状态&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;当表有字段具有&lt;code&gt;auto_now&lt;/code&gt;属性且你希望他能自动更新时，必须使用上边方法二的更新，不然auto_now字段不会更新&lt;/strong&gt;，也就是：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;_t = User.objects.get(id=1)
_t.username=&amp;#39;nick&amp;#39;
_t.is_active=True
_t.save()
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&#34;jsondict类型数据更新字段&#34;&gt;json/dict类型数据更新字段&lt;/h1&gt;
&lt;p&gt;目前主流的web开放方式都讲究前后端分离，分离之后前后端交互的数据格式大都用通用的json型，那么如何用最少的代码方便的更新json格式数据到数据库呢？同样可以使用如下两种方法：&lt;/p&gt;
&lt;p&gt;方法一：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;data = {&amp;#39;username&amp;#39;:&amp;#39;nick&amp;#39;,&amp;#39;is_active&amp;#39;:&amp;#39;0&amp;#39;}
User.objects.filter(id=1).update(**data)
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;同样这种方法不能自动更新具有&lt;code&gt;auto_now&lt;/code&gt;属性字段的值&lt;/li&gt;
&lt;li&gt;通常我们再变量前加一个星号(*)表示这个变量是元组/列表，加两个星号表示这个参数是字典&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;方法二：&lt;/p&gt;</description>
    </item>
    <item>
      <title>IDEA常用操作</title>
      <link>https://leochu.work/blog/tech/engineering/idea%E5%B8%B8%E7%94%A8%E6%93%8D%E4%BD%9C/</link>
      <pubDate>Sat, 02 Mar 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/idea%E5%B8%B8%E7%94%A8%E6%93%8D%E4%BD%9C/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;IDEA（IntelliJ IDEA）是业界公认的最好开发工具之一，当然好不好也因人而异，也不要刻意去争谁强谁弱，高手往往不在乎手中的兵器是什么的。个人而言，更高效的工具适合每个开发人员，在编写代码的时候花的时间少，就有更多的时间去设计&amp;hellip;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;目录&#34;&gt;目录&lt;/h2&gt;
&lt;p&gt;[toc]&lt;/p&gt;
&lt;h2 id=&#34;一概述&#34;&gt;一、概述&lt;/h2&gt;
&lt;p&gt;IDEA（IntelliJ IDEA）是业界公认的最好开发工具之一，当然好不好也因人而异，也不要刻意去争谁强谁弱，高手往往不在乎手中的兵器是什么的。个人而言，更高效的工具适合每个开发人员，在编写代码的时候花的时间少，就有更多的时间去设计代码，当然，使用一个陌生的 IDE，效率肯定是比不上自己熟练的 IDE 的，所以为了节省诸君的学习成本，也为了更快地去接纳和熟练 IDEA，所以周末之余，故作此文。&amp;mdash;- 一品江南&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;准备&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;所有的电脑软件都有着相同的 UI 框架、菜单结构，对于每一个开发人员来说，基本的文件操作、项目操作、工作空间操作不成问题，不会讲到。&lt;/li&gt;
&lt;li&gt;涉及的其他工具（Maven、Git 等）不会详细讲，只会讲到如何操作，想要深入学习，关注其他博文。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;二配置&#34;&gt;二、配置&lt;/h2&gt;
&lt;p&gt;在安装软件（JDK、Maven、Git、IDEA）搭建好环境后，要对 IDEA 进行一番配置，才能开始开发，每个人都有每个人的配置习惯，可以自己研究自己喜欢的配置，进入 IDEA 的配置 File | Settings（&lt;code&gt;Ctrl+Alt+S&lt;/code&gt;）开始配置。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;选择菜单或设置步骤使用 “|” 分开，后面操作一样&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;1-主题与行为&#34;&gt;1. 主题与行为&lt;/h3&gt;
&lt;p&gt;选择自己喜欢的主题：Appearance &amp;amp; Behavior | Appearance | Theme&lt;/p&gt;
&lt;p&gt;配置骚气的背景图片：Appearance &amp;amp; Behavior | Appearance | UI Options | Background Image…&lt;/p&gt;
&lt;p&gt;在配置中选择合适的窗口选项：Appearance &amp;amp; Behavior | Appearance | Window Options&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Animate windows：关闭动画效果&lt;/li&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Show memory indicator：显示内存使用情况&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Show tool window bars：关闭工具栏显示，按两次&lt;code&gt;Alt&lt;/code&gt;键可以显示&lt;/li&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Small labels in editor tabs：编辑器显示小标签&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;配置自己想看到的菜单项和工具栏：Appearance &amp;amp; Behavior | Menus and Toolbars&lt;/p&gt;</description>
    </item>
    <item>
      <title>Git配置SSH密钥</title>
      <link>https://leochu.work/blog/tech/engineering/git%E9%85%8D%E7%BD%AEssh%E5%AF%86%E9%92%A5/</link>
      <pubDate>Sat, 17 Feb 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/git%E9%85%8D%E7%BD%AEssh%E5%AF%86%E9%92%A5/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;本文由 &lt;a href=&#34;http://ksria.com/simpread/&#34;&gt;简悦 SimpRead&lt;/a&gt; 转码， 原文地址 &lt;a href=&#34;https://blog.csdn.net/weixin_41990913/article/details/91373362&#34;&gt;blog.csdn.net&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;初次安装 gitgit 需要配置用户名和邮箱，否则 git 会提示：please tell me who you are.&lt;/p&gt;
&lt;p&gt;你需要运行命令来配置你的用户名和邮箱：&lt;br&gt;
$ git config &amp;ndash;&lt;a href=&#34;https://so.csdn.net/so/search?q=global&amp;amp;spm=1001.2101.3001.7020&#34;&gt;global&lt;/a&gt; &lt;a href=&#34;http://user.name&#34;&gt;user.name&lt;/a&gt; “liuhanxia”&lt;br&gt;
$ git config &amp;ndash;global user.email &lt;a href=&#34;mailto:%22liuhanxia@51faguanggao.com&#34;&gt;&amp;ldquo;liuhanxia@51faguanggao.com&lt;/a&gt;&amp;rdquo;&lt;br&gt;
注意：（引号内请输入你自己设置的名字，和你自己的邮箱）此用户名和邮箱是 git 提交代码时用来显示你身份和联系方式的，并不是 &lt;a href=&#34;https://so.csdn.net/so/search?q=github&amp;amp;spm=1001.2101.3001.7020&#34;&gt;github&lt;/a&gt; 用户名和邮箱&lt;br&gt;
&lt;img loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/git_ssh_01.png&#34;&gt;&lt;br&gt;
git 使用 ssh 密钥&lt;br&gt;
git 支持 https 和 git 两种传输协议，github 分享链接时会有两种协议可选：git 协议链接图例、https 协议链接图例&lt;/p&gt;
&lt;p&gt;git 使用 https 协议，每次 pull, push 都会提示要输入密码，&lt;br&gt;
使用 git 协议，然后使用 ssh 密钥，这样免去每次都输密码的麻烦&lt;/p&gt;
&lt;p&gt;初次使用 git 的用户要使用 git 协议大概需要三个步骤：&lt;br&gt;
一、生成密钥对&lt;br&gt;
二、设置远程仓库（本文以 github 为例）上的公钥&lt;br&gt;
三、把 git 的 remote url 修改为 git 协议（以上两个步骤初次设置过以后，以后使用都不需要再次设置，此步骤视以后项目的 remote url 而定，如果以后其他项目的协议为 https 则需要此步骤）&lt;/p&gt;</description>
    </item>
    <item>
      <title>Git命令行</title>
      <link>https://leochu.work/blog/tech/engineering/git%E5%91%BD%E4%BB%A4%E8%A1%8C/</link>
      <pubDate>Sat, 03 Feb 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/git%E5%91%BD%E4%BB%A4%E8%A1%8C/</guid>
      <description>&lt;p&gt;&lt;img alt=&#34;img&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/git-command.jpg&#34;&gt;&lt;/p&gt;
&lt;h5 id=&#34;本地仓库链接远程仓库&#34;&gt;本地仓库链接远程仓库&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;git remote add origin &amp;lt;server&amp;gt;git@github.com:yourName/yourRepo.git&lt;/code&gt;&lt;/p&gt;
&lt;h5 id=&#34;创建一个叫做feature_x的分支并切换过去&#34;&gt;创建一个叫做“feature_x”的分支，并切换过去&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;git checkout -b feature_x&lt;/code&gt;&lt;/p&gt;
&lt;h5 id=&#34;再把新建的分支删掉&#34;&gt;再把新建的分支删掉：&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;git branch -d feature_x&lt;/code&gt;&lt;/p&gt;
&lt;h5 id=&#34;预览差异&#34;&gt;预览差异：&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;git diff &amp;lt;source_branch&amp;gt; &amp;lt;target_branch&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;h5 id=&#34;创建一个叫做-100-的标签&#34;&gt;创建一个叫做 &lt;em&gt;1.0.0&lt;/em&gt; 的标签：&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;git tag 1.0.0 1b2e1d63ff&lt;/code&gt;&lt;/p&gt;
&lt;h5 id=&#34;想commit自动来提交本地修改我们可以使用-a标识&#34;&gt;想commit自动来提交本地修改，我们可以使用-a标识&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;git commit -a -m &amp;quot;Changed some files&amp;quot;&lt;/code&gt;
&lt;em&gt;git commit 命令的-a选项可将所有&lt;strong&gt;被修改或者已删除的且已经被git管理的文档&lt;/strong&gt;提交到仓库中&lt;/em&gt;
&lt;em&gt;千万注意，-a不会造成新文件被提交，只能修改。&lt;/em&gt;&lt;/p&gt;
&lt;h5 id=&#34;内建的图形化-git&#34;&gt;内建的图形化 git：&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;gitk&lt;/code&gt;&lt;/p&gt;
&lt;h5 id=&#34;彩色的-git-输出&#34;&gt;彩色的 git 输出：&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;git config color.ui true&lt;/code&gt;&lt;/p&gt;
&lt;h5 id=&#34;使用git-gui创建sshkey及查看&#34;&gt;使用git gui创建sshkey及查看：&lt;/h5&gt;
&lt;p&gt;&lt;img alt=&#34;image-20230213164607434&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/image-20230213164607434.png&#34;&gt;&lt;/p&gt;
&lt;h5 id=&#34;命令行创建ssh-key&#34;&gt;命令行创建ssh key：&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;ssh-keygen -t rsa -C &amp;quot;your_email@youremail.com&amp;quot;&lt;/code&gt;
&lt;em&gt;后面的&lt;code&gt;your_email@youremail.com&lt;/code&gt;改为你在github上注册的邮箱，之后会要求确认路径和输入密码，我们这使用默认的一路回车就行。成功的话会在&lt;code&gt;~/&lt;/code&gt;下生成&lt;code&gt;.ssh&lt;/code&gt;文件夹，进去，打开&lt;code&gt;id_rsa.pub&lt;/code&gt;，复制里面的&lt;code&gt;key&lt;/code&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;h5 id=&#34;验证是否成功在git-bash下输入&#34;&gt;验证是否成功，在git bash下输入：&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;ssh -T git@github.com&lt;/code&gt;&lt;/p&gt;
&lt;h5 id=&#34;如果要查看指定文件的修改记录可以使用-git-blame-命令格式如下&#34;&gt;如果要查看指定文件的修改记录可以使用 git blame 命令，格式如下：&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;git blame &amp;lt;file&amp;gt;&lt;/code&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Git服务器搭建</title>
      <link>https://leochu.work/blog/tech/engineering/git%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%90%AD%E5%BB%BA/</link>
      <pubDate>Sat, 20 Jan 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/git%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%90%AD%E5%BB%BA/</guid>
      <description>&lt;p&gt;上一章节中我们远程仓库使用了 Github，Github 公开的项目是免费的，2019 年开始 Github 私有存储库也可以无限制使用。&lt;/p&gt;
&lt;p&gt;这当然我们也可以自己搭建一台 Git 服务器作为私有仓库使用。&lt;/p&gt;
&lt;p&gt;接下来我们将以 Centos 为例搭建 Git 服务器。&lt;/p&gt;
&lt;h3 id=&#34;1安装git&#34;&gt;1、安装Git&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-devel
$ yum install git
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;接下来我们 创建一个git用户组和用户，用来运行git服务：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ groupadd git
$ useradd git -g git
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;2创建证书登录&#34;&gt;2、创建证书登录&lt;/h3&gt;
&lt;p&gt;收集所有需要登录的用户的公钥，公钥位于id_rsa.pub文件中，把我们的公钥导入到/home/git/.ssh/authorized_keys文件里，一行一个。&lt;/p&gt;
&lt;p&gt;如果没有该文件创建它：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ cd /home/git/
$ mkdir .ssh
$ chmod 755 .ssh
$ touch .ssh/authorized_keys
$ chmod 644 .ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;3初始化git仓库&#34;&gt;3、初始化Git仓库&lt;/h3&gt;
&lt;p&gt;首先我们选定一个目录作为Git仓库，假定是/home/gitrepo/runoob.git，在/home/gitrepo目录下输入命令：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ cd /home
$ mkdir gitrepo
$ chown git:git gitrepo/
$ cd gitrepo

$ git init --bare runoob.git
Initialized empty Git repository in /home/gitrepo/runoob.git/
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;以上命令Git创建一个空仓库，服务器上的Git仓库通常都以.git结尾。然后，把仓库所属用户改为git：&lt;/p&gt;</description>
    </item>
    <item>
      <title>ai栈</title>
      <link>https://leochu.work/blog/tech/ai/ai%E6%8A%80%E6%9C%AF%E6%A0%88/</link>
      <pubDate>Sat, 06 Jan 2024 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/ai/ai%E6%8A%80%E6%9C%AF%E6%A0%88/</guid>
      <description>&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;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;strong&gt;文档整理 / 项目重构 / 架构设计&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Claude Code（基于 Claude Opus）&lt;/td&gt;
          &lt;td&gt;高质量理解长上下文，支持跨文件重构和工程分析；生成方案/代码，但需要外部环境执行&lt;/td&gt;
          &lt;td&gt;pro订阅&lt;/td&gt;
          &lt;td&gt;claude&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;写代码 / 单文件实现&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;OpenAI Codex（GPT-Code 系列）&lt;/td&gt;
          &lt;td&gt;自动生成可运行代码，适合函数、模块、脚本任务；执行依赖你的环境或接口&lt;/td&gt;
          &lt;td&gt;plus订阅&lt;/td&gt;
          &lt;td&gt;openAi&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;实时代码辅助 / IDE 提示&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;GitHub Copilot&lt;/td&gt;
          &lt;td&gt;IDE 插件，提供智能补全和片段建议，不提供 API&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;对话 / 问答 /策略讨论&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;ChatGPT Plus&lt;/td&gt;
          &lt;td&gt;快速交互、概念解释、方案讨论&lt;/td&gt;
          &lt;td&gt;plus订阅&lt;/td&gt;
          &lt;td&gt;openAi&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;机械重复 / 简单批处理任务&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;国内轻量模型&lt;/td&gt;
          &lt;td&gt;低成本处理大量重复操作或简单格式化任务&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;miniMax&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;自动化执行 / 跨渠道智能代理&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;OpenClaw&lt;/td&gt;
          &lt;td&gt;可自托管的 AI Agent 框架；整合多模型、消息渠道和技能；能持续管理任务、执行脚本、调用 API 和操作工具；适合自动化工作流和多通道触发，需配置和监管&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;</description>
    </item>
    <item>
      <title>数据模型字段及属性详解</title>
      <link>https://leochu.work/blog/tech/python/django/%E6%95%B0%E6%8D%AE%E6%A8%A1%E5%9E%8B%E5%AD%97%E6%AE%B5%E5%8F%8A%E5%B1%9E%E6%80%A7%E8%AF%A6%E8%A7%A3/</link>
      <pubDate>Sun, 24 Dec 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/python/django/%E6%95%B0%E6%8D%AE%E6%A8%A1%E5%9E%8B%E5%AD%97%E6%AE%B5%E5%8F%8A%E5%B1%9E%E6%80%A7%E8%AF%A6%E8%A7%A3/</guid>
      <description>&lt;h1 id=&#34;数据模型字段及属性详解&#34;&gt;数据模型字段及属性详解&lt;/h1&gt;
&lt;p&gt;在设计数据模型的时候，我们需要根据不同的需求，设计不同的表和不同的字段。不同的字段也可以设置不同的参数。&lt;/p&gt;
&lt;p&gt;一个模型（model）就是一个单独的、确定的数据的信息源，包含了数据的字段和操作方法。Django是通过Model操作数据库，不管你数据库的类型是MySql或者Sqlite，Django它自动帮你生成相应数据库类型的SQL语句，所以不需要关注SQL语句和类型，对数据的操作Django帮我们自动完成。只要回写Model就可以了！&lt;/p&gt;
&lt;p&gt;django根据代码中定义的类来自动生成数据库表。我们写的类表示数据库的表，如果根据这个类创建的对象是数据库表里的一行数据，对象.id 对象.value是每一行里的数据。&lt;/p&gt;
&lt;p&gt;基本的原则如下：
每个模型在Django中的存在形式为一个Python类
每个模型都是django.db.models.Model的子类
模型里的每个类代表数据库中的一个表
模型的每个字段（属性）代表数据表的某一列
Django将自动为你生成数据库访问API&lt;/p&gt;
&lt;p&gt;Django这种操作数据库的方式，我们把它叫做：&lt;strong&gt;关系对象映射（Object Relational Mapping，简称ORM）。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;我们之前有在&lt;a href=&#34;https://www.django.cn/course/show-11.html&#34;&gt;管理后台与model模型&lt;/a&gt;这文章里简单的接触过。里面的models代码：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;class Category(models.Model):
    name = models.CharField(&amp;#39;分类&amp;#39;,max_length=100)
    
class Tags(models.Model):
    name = models.CharField(&amp;#39;标签&amp;#39;,max_length=100)
    
class Article(models.Model):
    title = models.CharField(&amp;#39;标题&amp;#39;,max_length=70)
    intro = models.TextField(&amp;#39;摘要&amp;#39;, max_length=200, blank=True)
    category = models.ForeignKey(Category, on_delete=models.CASCADE, verbose_name=&amp;#39;分类&amp;#39;, default=&amp;#39;1&amp;#39;)
    tags = models.ManyToManyField(Tags, blank=True)
    body = models.TextField()
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name=&amp;#39;作者&amp;#39;)
    created_time = models.DateTimeField(&amp;#39;发布时间&amp;#39;,auto_now_add=True)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;字段是模型中最重要的内容之一，也是唯一必须的部分。字段在Python中表现为一个类属性，体现了数据表中的一个列。Django不允许下面两种字段名：1、与Python关键字冲突。2、字段名中不能有两个以上下划线在一起，因为两个下划线是Django的查询语法。也不要使用clean、save、delete等Django内置的模型API名字，防止命名冲突。&lt;/p&gt;
&lt;p&gt;每一个字段都是一个类属性，每个类属性表示数据表中的一个列。上面那个models生成数据后，在数据库里是这样的：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;1.jpg&#34; loading=&#34;lazy&#34; src=&#34;https://www.django.cn/media/upimg/1_20180727113014_518.jpg&#34;&gt;&lt;/p&gt;
&lt;p&gt;表名由Django自动生成，例如我们的Article类会自动生成为blog_Article，默认格式为“应用名称+下划线+小写类名”。如果你不指定主键，Django默认自动创建自增主键id。每个APP应用都有独立属于自己的模型，创建了APP之后，在使用它之前，你需要先在settings文件中的INSTALLED_APPS 处，注册models.py文件所在的app名称。看清楚了，是注册app，不是模型，也不是models.py。关于settings，我们前面也有讲解过，具体可查看文章：&lt;a href=&#34;https://www.django.cn/course/show-10.html&#34;&gt;全局配置settings详解&lt;/a&gt;。例如我们创建了名为blog的应用APP则在settings这样写：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;INSTALLED_APPS = [
#...
&amp;#39;blog&amp;#39;,  #我们要添加的应用名
#...
]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;当你每次对模型进行增、删、修改时，我们都需要执行python manage.py makemigrations请务必执命令，然后再执行：python manage.py migrate，让操作实际应用到数据库上。&lt;/p&gt;</description>
    </item>
    <item>
      <title>模块地狱</title>
      <link>https://leochu.work/blog/tech/engineering/%E6%A8%A1%E5%9D%97%E5%9C%B0%E7%8B%B1/</link>
      <pubDate>Sun, 10 Dec 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/%E6%A8%A1%E5%9D%97%E5%9C%B0%E7%8B%B1/</guid>
      <description>&lt;p&gt;个人理解: 有点类似依赖冲突,循环依赖&lt;/p&gt;
&lt;ul&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;/ul&gt;</description>
    </item>
    <item>
      <title>开源许可证</title>
      <link>https://leochu.work/blog/tech/engineering/%E5%BC%80%E6%BA%90%E8%AE%B8%E5%8F%AF%E8%AF%81/</link>
      <pubDate>Sun, 26 Nov 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/%E5%BC%80%E6%BA%90%E8%AE%B8%E5%8F%AF%E8%AF%81/</guid>
      <description>&lt;p&gt;&lt;img alt=&#34;Pasted image 20230426182936.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230426182936.png&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>开发流程</title>
      <link>https://leochu.work/blog/tech/engineering/%E5%BC%80%E5%8F%91%E6%B5%81%E7%A8%8B/</link>
      <pubDate>Sun, 12 Nov 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/%E5%BC%80%E5%8F%91%E6%B5%81%E7%A8%8B/</guid>
      <description>&lt;h2 id=&#34;1-开发流程&#34;&gt;1. 开发流程&lt;/h2&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20230327103333.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230327103333.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;**说明：**此开发流程符合大部分需求场景，少数需求可能流程会有所增减。&lt;/p&gt;
&lt;h2 id=&#34;2-流程说明&#34;&gt;2. 流程说明&lt;/h2&gt;
&lt;hr&gt;
&lt;h4 id=&#34;21-需求评审&#34;&gt;2.1 需求评审&lt;/h4&gt;
&lt;p&gt;详细了解本次需求的背景和细节，并讨论需求的可行性。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;比如：&lt;/strong&gt;     &lt;/p&gt;
&lt;p&gt;当前需求是否明确? 新需求是什么?&lt;br&gt;
需求背景及解决什么问题?&lt;br&gt;
如果需求复杂程度大，提出是否需要分阶段实施?&lt;br&gt;
需求完成的期望指标是什么? 如何评判? 如何交付?&lt;br&gt;
技术能否实现、逻辑是否有问题？&lt;br&gt;
进入开发阶段测试，遇到问题与谁对接，来协调解决问题?&lt;br&gt;
如果需求复杂请让需求方拆解需求去描述要达到的目的。&lt;br&gt;
如果需求未做到目的明确，清晰合理，请让需求方解决疑问点。&lt;br&gt;
需求对接完，请邮件告知。&lt;/p&gt;
&lt;h4 id=&#34;22-技术评审&#34;&gt;2.2 技术评审&lt;/h4&gt;
&lt;p&gt;阐述详细的技术实现方案，评估一下是否有不合理之处，比如表结构如何设计、接口怎么定义、有没有技术难点等。&lt;/p&gt;
&lt;h4 id=&#34;23-开发--测试排期&#34;&gt;2.3 开发 &amp;amp; 测试排期&lt;/h4&gt;
&lt;p&gt;评估具体的工作量，根据工作量安排各个步骤要完成的截止日期。&lt;/p&gt;
&lt;h4 id=&#34;24-输出开发设计文档&#34;&gt;2.4 输出开发设计文档&lt;/h4&gt;
&lt;p&gt;此文档放在 confluence 上，大致包含需求背景、开发设计（技术方案）、排期计划、开发流程的具体内容、附录等。&lt;strong&gt;需求背景、开发设计（技术方案）、排期计划要在开发测试开始前书写完成，其他部分可以根据进度补充完善。&lt;/strong&gt;&lt;/p&gt;
&lt;h4 id=&#34;25-开发--测试&#34;&gt;2.5 开发 &amp;amp; 测试&lt;/h4&gt;
&lt;p&gt;根据技术方案和排期，具体实现。&lt;/p&gt;
&lt;h4 id=&#34;26-需求方验收&#34;&gt;2.6 需求方验收&lt;/h4&gt;
&lt;p&gt;验收阶段，开发如有 bug 修改 bug，可以提前提供部分样例结果进行预验收。&lt;/p&gt;
&lt;h4 id=&#34;27-生产部署&#34;&gt;2.7 生产部署&lt;/h4&gt;
&lt;p&gt;根据具体环境部署。&lt;/p&gt;
&lt;h4 id=&#34;28-需求复盘总结&#34;&gt;2.8 需求复盘总结&lt;/h4&gt;
&lt;p&gt;复盘一下问题主要出在哪里，以后如何规避，哪些优点可以以后借鉴等。&lt;/p&gt;
&lt;h2 id=&#34;3-其他注意事项&#34;&gt;3. 其他注意事项&lt;/h2&gt;
&lt;hr&gt;
&lt;h4 id=&#34;31-关于对接和验收阶段&#34;&gt;3.1 关于对接和验收阶段&lt;/h4&gt;
&lt;p&gt;首版需求已评审过的前提下，在此阶段如果不可避免出现需求变更频繁和很多不确定的时候，要明确告知需求方批量提供需求点或完善点，避免随时出现一个接一个，导致此需求一直完不成。&lt;/p&gt;
&lt;p&gt;最好补充一次批量提完，如果第两个及以上批次，建议需求当需求变更处理。&lt;/p&gt;
&lt;p&gt;开发要合理评估，尽量避免开发不合理需求。&lt;/p&gt;
&lt;h2 id=&#34;4-附件&#34;&gt;4. 附件&lt;/h2&gt;
&lt;hr&gt;
&lt;p&gt;Java 开发手册:!泰山版.pdf&lt;/p&gt;</description>
    </item>
    <item>
      <title>技术债</title>
      <link>https://leochu.work/blog/tech/engineering/%E6%8A%80%E6%9C%AF%E5%80%BA/</link>
      <pubDate>Sun, 29 Oct 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/%E6%8A%80%E6%9C%AF%E5%80%BA/</guid>
      <description>&lt;p&gt;关于技术债务的文章，尽管实践中会堆积技术债，但这个概念并不在我们的工作中频繁出现。这篇文章就系统性讲讲技术债，让大家避免知其然，不知其所以然。&lt;/p&gt;
&lt;p&gt;一、技术债是什么&lt;/p&gt;
&lt;p&gt;技术负债（英语：Technical debt），又译技术债，也称为设计负债（design debt）、代码负债（code debt），是编程及软件工程中的借鉴了财务债务的系统隐喻。指开发人员为了加速软件开发，在应该采用最佳方案时进行了妥协，改用了短期内能加速软件开发的方案，从而在未来给自己带来的额外开发负担。这种技术上的选择，就像一笔债务一样，虽然眼前看起来可以得到好处，但必须在未来偿还。软件工程师必须付出额外的时间和精力持续修复之前的妥协所造成的问题及副作用，或是进行重构，把架构改善为最佳实现方式。&lt;/p&gt;
&lt;p&gt;1992 年，沃德 · 坎宁安首次将技术的复杂比作为负债。第一次发布代码，就好比借了一笔钱。只要通过不断重写来偿还债务，小额负债便可以加速开发。但久未偿还债务会引发危险。复用马马虎虎的代码，类似于负债的利息。整个部门有可能因为松散的实现，不完全的面向对象的设计或其他诸如此类的负债而陷入窘境。&lt;/p&gt;
&lt;p&gt;二、技术债表现&lt;/p&gt;
&lt;p&gt;技术债与其他债务本身一样，是一种透支行为，通过牺牲未来来满足当下的一些需求。也跟其他债务一样，技术债务也有利息，而且随着时间利滚利，会成为埋在项目里的定时炸弹。如果产品长期的可持续的发展，那么技术债的重要性是毋庸置疑的。&lt;/p&gt;
&lt;p&gt;技术债务的本质是产品的结构阻碍了进步，表现出来的症状有：无法轻易重构产品以满足市场需求；组件之间的依赖性过多，体系结构不良；缺陷太多，结构不良；难以理解，难以改变。&lt;/p&gt;
&lt;p&gt;技术债务的后果有偿还技术债务造成时间浪费，员工满意度降低带来士气低落，因解决遗留代码问题而错过优质项目造成人才流失，产品质量降低造成客户满意度下降，技术债务限制创新能力、扼杀创造性等诸多问题。&lt;/p&gt;
&lt;p&gt;技术债不单单是技术债，它就像一个垃圾堆，久而久之不处理，慢慢周围就会产生更多的垃圾，因此产生的 “破窗效应” 更加是会对未来的项目环境造成很大的影响，大家也会逐渐丧失维护环境的信心。所以在讨论技术债的时候不仅仅是讨论技术债本身，技术债对团队追求质量的信心、对大家维护环境整洁的积极性都会造成很大的影响。&lt;/p&gt;
&lt;p&gt;MartinFowler 把技术债分为四个象限，如下图所示：&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/eac4b74543a98226442e205e821997094b90eb7b.jpeg&#34;&gt;&lt;/p&gt;
&lt;p&gt;三、技术债产生的原因&lt;/p&gt;
&lt;p&gt;●业务压力：为了满足业务的快速要求，在必要的修改并没有完成时就匆匆发布，这些未完成的修改就形成了技术负债。&lt;/p&gt;
&lt;p&gt;●缺少过程和理解：业务人员不清楚不理解技术负债的概念，在决策时就不会考虑到其带来的影响。&lt;/p&gt;
&lt;p&gt;●模块之间解耦不够：功能没有模块化，软件柔性不够，不足适应业务变化的要求。&lt;/p&gt;
&lt;p&gt;●缺少配套的自动化测试：导致鼓励快速而风险很大的 “创可贴” 式的 BUG 修复。&lt;/p&gt;
&lt;p&gt;●缺少必要文档：需求和代码都没有必要的支撑性文档或注释。&lt;/p&gt;
&lt;p&gt;●缺少协作：组织中的知识共享和业务效率较低，或者初级开发者缺少必要的指导。&lt;/p&gt;
&lt;p&gt;●重构延迟：在开发的过程中，某些部分的代码会变得难以控制，这时候就需要进行重构，以适应将来的需求变化。重构越是推迟，这些已有的代码被使用的越多，形成的技术负债就越多，直到重构完成。&lt;/p&gt;
&lt;p&gt;●不遵循标准或最佳实践：忽略了已有的业界标准、框架、技术和最佳实践。&lt;/p&gt;
&lt;p&gt;●缺少相关技能：开发人员有时候技能缺失，并不知道如何编写优雅的代码。&lt;/p&gt;
&lt;p&gt;四、如何 “还债”？&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;技术债可视化&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;尽可能公开技术债，一开始就与团队，利益相关方一起权衡利弊，并明确告知影响与解决方案。平等沟通，相互理解。让技术债在业务层面、技术层面可见。&lt;/p&gt;
&lt;p&gt;可以在组织资产负债表的财产债中新增两列：短期技术债和长期技术债。还可以用用跟踪开发速率的方式体现技术债对于产品的影响。&lt;/p&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;不同的债要对症下药&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;技术债的状态可以分类为偶然技术债、已知技术债和目标技术债。&lt;/p&gt;
&lt;p&gt;偿还技术债时应遵循如下原则：&lt;/p&gt;
&lt;p&gt;1）确定已知技术债必须还。&lt;/p&gt;
&lt;p&gt;2）发现偶然技术债，立即还。&lt;/p&gt;
&lt;p&gt;3）每个冲刺确定一定数量的已知技术债作为目标技术债，在当前冲刺中偿还。&lt;/p&gt;
&lt;p&gt;4）无需偿还的技术债是行将就木的产品、一次性原型和短命产品。&lt;/p&gt;
&lt;p&gt;五、如何避免 “欠债”&lt;/p&gt;
&lt;p&gt;与其后期吭哧吭哧还债填坑，不如从一开始就尽量避免欠下技术债务。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;避免使用过时的技术&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;遗留应用程序、过时的技术以及不同的平台和流程可能会使组织陷入沉重的技术债务，迫使其推迟基本的现代化计划。DNS 和流量管理技术提供商 NS1 的联合创始人兼首席执行官 Kris Beevers 说：“技术债务将大量金钱和宝贵的时间浪费在系统和应用程序上，而这些系统和应用程序并不是为现代企业所需的规模和速度而打造的。”&lt;/p&gt;
&lt;p&gt;旧资产和老方法也往往充斥着安全漏洞，难以集成和自动化，并且很可能不再更新。 Beevers 指出：“寻找人才来管理基于复杂或过时的代码构建的遗留应用程序也是一个日益严峻的难题。坚持采用过时技术不仅会消耗宝贵的预算，而且还会阻碍公司创新和保持竞争力的能力。”&lt;/p&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;参考敏捷实践&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;有越来越多的组织渐渐接受敏捷软件开发，这是将方法交给协作、自行组织的团队和跨职能团队的一系列方法和实践。如果这种方法得到严格应用，敏捷开发使组织可以避免技术债务，其方法是快速且以迭代的方式创建和发布新产品。Dodd 说：“这一过程将新产品和新功能尽快并逐步地交到用户手中。” 随着新版本的交付，各种改进和问题都得到了解决，这使技术债务的积累不太可能产生。&lt;/p&gt;
&lt;p&gt;敏捷方法认识到项目在生命周期中从未真正完成过，并且也从来都不是完美的。“同时，敏捷方法专注于…… 针对能力和质量的简化了的开发”，Dodd 说。重要功能往往要频繁地开发，测试并投入生产。敏捷团队可能不会发布软件的 “全面（Big Bang）” 方法，而是每年发布几次重大升级。Dodd 指出：“这可以使产品保持相当平稳的发展，还可以帮助用户避免重大的中断事件。”&lt;/p&gt;</description>
    </item>
    <item>
      <title>关于maven项目的配置文件</title>
      <link>https://leochu.work/blog/tech/engineering/maven%E9%A1%B9%E7%9B%AE%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6/</link>
      <pubDate>Sun, 15 Oct 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/maven%E9%A1%B9%E7%9B%AE%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6/</guid>
      <description>&lt;p&gt;把项目的配置文件按运行环境做一下区分，比如开发环境和线上环境使用的使用不同的配置文件，这里我们基于项目的 &lt;code&gt;resoures/&lt;/code&gt; 目录来实现：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# resoures 目录
.
├── env
│   ├── config.dev.properties
│   └── config.prod.properties
└── config.properties
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;我们创建了一个 &lt;code&gt;config.properties&lt;/code&gt; 文件来配置项目的常用配置数据，如， &lt;code&gt;kafaka&lt;/code&gt; 、 &lt;code&gt;redis&lt;/code&gt; 等连接配置等。&lt;/p&gt;
&lt;p&gt;然后创建一个 &lt;code&gt;env&lt;/code&gt; 子目录，并创建两个环境对应的配置文件，我们希望不同的环境当中使用不同的配置。当然，光是创建这些文件，是无法让文件实现自动按照运行环境自动实现文件匹配的，我们还需要配置 &lt;code&gt;pom.xml&lt;/code&gt; 文件：&lt;/p&gt;
&lt;p&gt;首先，找到 &lt;code&gt;&amp;lt;build&amp;gt;&lt;/code&gt; 配置字段，添加文件路径：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;build&amp;gt;
    &amp;lt;!-- Loading all ${} --&amp;gt;
    &amp;lt;filters&amp;gt;
        &amp;lt;filter&amp;gt;src/main/resources/env/config.${env}.properties&amp;lt;/filter&amp;gt;
    &amp;lt;/filters&amp;gt;
    &amp;lt;!-- Map ${} into resources --&amp;gt;
    &amp;lt;resources&amp;gt;
        &amp;lt;resource&amp;gt;
            &amp;lt;directory&amp;gt;src/main/resources&amp;lt;/directory&amp;gt;
            &amp;lt;filtering&amp;gt;true&amp;lt;/filtering&amp;gt;
            &amp;lt;includes&amp;gt;
                &amp;lt;include&amp;gt;*.properties&amp;lt;/include&amp;gt;
            &amp;lt;/includes&amp;gt;
        &amp;lt;/resource&amp;gt;
    &amp;lt;/resources&amp;gt;
    &amp;lt;!-- 省略之后若干行 --&amp;gt;
&amp;lt;/build&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上述代码目的是告诉构建工具，在构建的时候需要加载 &lt;code&gt;resoures&lt;/code&gt; 目录的配置文件参与构建，并且使用 &lt;code&gt;${env}&lt;/code&gt; 环境变量来决定具体加载的名称。&lt;/p&gt;
&lt;p&gt;因此，我们还需要指定 &lt;code&gt;${env}&lt;/code&gt; 的环境变量配置，在 &lt;code&gt;&amp;lt;profiles&amp;gt;&lt;/code&gt; 标签下，移除默认的 &lt;code&gt;&amp;lt;profile&amp;gt;&lt;/code&gt; 配置内容，新建两份环境配置 &lt;code&gt;dev&lt;/code&gt; 和 &lt;code&gt;prod&lt;/code&gt; 的 &lt;code&gt;profile&lt;/code&gt; 文件配置：&lt;/p&gt;</description>
    </item>
    <item>
      <title>关于设计模式</title>
      <link>https://leochu.work/blog/tech/engineering/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E6%A6%82%E8%BF%B0/</link>
      <pubDate>Sun, 01 Oct 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E6%A6%82%E8%BF%B0/</guid>
      <description>&lt;h2 id=&#34;策略模式strategy-pattern&#34;&gt;【策略模式】（Strategy Pattern）&lt;/h2&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20230420121518.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230420121518.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;其中的Context是一个所谓的“上下文”，不一定非得是个类，也可以只是一个函数/方法。最关键的是，我们其实根本不需要ConcreteStrategyX类，也不需要它们的对象。我们要的只是一个execute函数而已，我们甚至连execute这个函数名都不需要，只要能执行它就行。&lt;/p&gt;
&lt;p&gt;看看函数式编程是怎么玩的（这里以大家都熟悉的JavaScript为例）：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;context&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;func&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// 做些什么...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;result&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;func&lt;/span&gt;()  &lt;span style=&#34;color:#75715e&#34;&gt;// 有需要的话可以传参
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// 再做些什么...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;context&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// 做些什么...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;123&lt;/span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// 是否需要返回值看需求
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;一个匿名函数参数&lt;code&gt;func&lt;/code&gt;搞定。&lt;/p&gt;
&lt;p&gt;Java能搞出这种类图来，全都是因为Java没有一等公民的函数，所以函数必须依附于类（静态方法）或者对象（非静态方法）。而玩静态方法又没法玩多态，而且类不能当成参数传递给其他函数/方法，所以只能用对象携带方法。而对象的方法必须有个名称，为了统一，就叫execute。由于需要多态，所以我们必须提一个接口出来，在接口里声明execute的方法签名。所有这一切说白了都是为了讨好Java编译器，否则它会给你颜色（red）看。&lt;/p&gt;
&lt;p&gt;当然，自从Java有了函数式接口和lambda后一定程度上也能玩函数式编程了。&lt;/p&gt;
&lt;h2 id=&#34;观察者模式observer-pattern&#34;&gt;【观察者模式】（Observer Pattern）&lt;/h2&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20230420121526.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230420121526.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;这个在JS里大家已经熟悉到不能再熟悉了：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;someButton&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;onclick&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;event&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// 处理点击事件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;又是一个匿名函数搞定！上图里的&lt;code&gt;Subject#attach&lt;/code&gt;在这里就是直接赋值。&lt;code&gt;Subject#detach&lt;/code&gt;就是赋空值。&lt;code&gt;Subject#notify&lt;/code&gt;就是调用一下匿名函数而已。而&lt;code&gt;Observer#update&lt;/code&gt;就是匿名函数本身。&lt;/p&gt;
&lt;h2 id=&#34;访问者模式visitor-pattern&#34;&gt;【访问者模式】（Visitor Pattern）&lt;/h2&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20230420121532.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230420121532.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;能整成这样我也是服了。说白了不就是访问者需要判断一下元素类型嘛。直接套用策略模式，在匿名函数里if-else一下不就行了？（当然还有其他方式，比如引入一个工厂。有模式匹配的函数式编程语言如Haskell、Erlang、Elixir等玩起来更简单）。&lt;/p&gt;
&lt;h2 id=&#34;装饰器模式decorator-pattern&#34;&gt;【装饰器模式】（Decorator Pattern）&lt;/h2&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20230420121538.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230420121538.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;这才是函数式编程的魅力所在！&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;core1&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;arg1&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;arg2&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// 做些啥
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;123&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;core2&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;arg&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// 做些啥
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;456&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;decorate&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;core&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// 做些准备工作
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;// 做些啥，甚至可以改变参数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;ret&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;core&lt;/span&gt;(...&lt;span style=&#34;color:#a6e22e&#34;&gt;arguments&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;// 做些啥，甚至可以改变返回值
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;ret&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;decorated1&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;decorate&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;core1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;decorated2&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;decorate&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;core2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;酷吧？又是匿名函数搞定！只不过这次的匿名函数是返回值。&lt;/p&gt;</description>
    </item>
    <item>
      <title>分页</title>
      <link>https://leochu.work/blog/tech/python/django/%E5%88%86%E9%A1%B5/</link>
      <pubDate>Sun, 17 Sep 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/python/django/%E5%88%86%E9%A1%B5/</guid>
      <description>&lt;h1 id=&#34;分页-paginator&#34;&gt;分页 Paginator&lt;/h1&gt;
&lt;hr&gt;
&lt;p&gt;分页功能是几乎所有的网站上都需要提供的功能，当你要展示的条目比较多时，必须进行分页，不但能减小数据库读取数据压力，也有利于用户浏览。&lt;/p&gt;
&lt;p&gt;Django又很贴心的为我们提供了一个Paginator分页工具，但是不幸的是，这个工具功能差了点，不好添加CSS样式，所以前端的展示效果比较丑。如果你能力够，自己编写一个分页器，然后提交给Django官方吧，争取替代掉这个当前的分页器，我看好你哦！&lt;/p&gt;
&lt;p&gt;但不管怎么样，当前的Paginator分页器，还是要学一下用一下的。&lt;/p&gt;
&lt;h2 id=&#34;一实例展示&#34;&gt;一、实例展示&lt;/h2&gt;
&lt;p&gt;分页功能位于&lt;code&gt;django.core.paginator&lt;/code&gt;模块。&lt;/p&gt;
&lt;p&gt;向&lt;code&gt;Paginator&lt;/code&gt;提供包含一些对象的列表，以及你想每一页显示几条，比如每页5条、10条、20条、100条等等，它就会为你提供访问的一系列API方法，示例如下：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; from django.core.paginator import Paginator
&amp;gt;&amp;gt;&amp;gt; objects = [&amp;#39;john&amp;#39;, &amp;#39;paul&amp;#39;, &amp;#39;george&amp;#39;, &amp;#39;ringo&amp;#39;]
&amp;gt;&amp;gt;&amp;gt; p = Paginator(objects, 2)  # 对objects进行分页，虽然objects只是个字符串列表，但没关系，一样用。每页显示2条。

&amp;gt;&amp;gt;&amp;gt; p.count   # 对象个数
4
&amp;gt;&amp;gt;&amp;gt; p.num_pages  # 总共几页
2
&amp;gt;&amp;gt;&amp;gt; type(p.page_range)  # `&amp;lt;type &amp;#39;rangeiterator&amp;#39;&amp;gt;` in Python 2.
&amp;lt;class &amp;#39;range_iterator&amp;#39;&amp;gt;
&amp;gt;&amp;gt;&amp;gt; p.page_range  # 分页范围
range(1, 3)

&amp;gt;&amp;gt;&amp;gt; page1 = p.page(1) # 获取第一页
&amp;gt;&amp;gt;&amp;gt; page1
&amp;lt;Page 1 of 2&amp;gt;
&amp;gt;&amp;gt;&amp;gt; page1.object_list # 获取第一页的对象
[&amp;#39;john&amp;#39;, &amp;#39;paul&amp;#39;]

&amp;gt;&amp;gt;&amp;gt; page2 = p.page(2)
&amp;gt;&amp;gt;&amp;gt; page2.object_list
[&amp;#39;george&amp;#39;, &amp;#39;ringo&amp;#39;]
&amp;gt;&amp;gt;&amp;gt; page2.has_next()  # 判断是否有下一页
False
&amp;gt;&amp;gt;&amp;gt; page2.has_previous()# 判断是否有上一页
True
&amp;gt;&amp;gt;&amp;gt; page2.has_other_pages() # 判断是否有其它页
True
&amp;gt;&amp;gt;&amp;gt; page2.next_page_number() # 获取下一页的页码
Traceback (most recent call last):
...
EmptyPage: That page contains no results
&amp;gt;&amp;gt;&amp;gt; page2.previous_page_number() # 获取上一页的页码
1
&amp;gt;&amp;gt;&amp;gt; page2.start_index() # 从1开始计数的当前页的第一个对象
3
&amp;gt;&amp;gt;&amp;gt; page2.end_index() # 从1开始计数的当前页最后1个对象
4

&amp;gt;&amp;gt;&amp;gt; p.page(0)  # 访问不存在的页面
Traceback (most recent call last):
...
EmptyPage: That page number is less than 1
&amp;gt;&amp;gt;&amp;gt; p.page(3) # 访问不存在的页面
Traceback (most recent call last):
...
EmptyPage: That page contains no results
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;简单地说，使用Paginator分四步走：&lt;/p&gt;</description>
    </item>
    <item>
      <title>定制Admin管理后台</title>
      <link>https://leochu.work/blog/tech/python/django/%E5%AE%9A%E5%88%B6admin%E7%AE%A1%E7%90%86%E5%90%8E%E5%8F%B0/</link>
      <pubDate>Sun, 03 Sep 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/python/django/%E5%AE%9A%E5%88%B6admin%E7%AE%A1%E7%90%86%E5%90%8E%E5%8F%B0/</guid>
      <description>&lt;p&gt;在&lt;a href=&#34;https://www.django.cn/course/show-11.html&#34;&gt;管理后台与model模型&lt;/a&gt;文章里，我们曾经有一个操作，就是在admin.py里注册blog应用，这样blog应用才会在后台显示出来，我们才能在后台对这个应用进行管理。这就是Django自带的后台管理的特色之一，它可以让我们快速便捷管理数据，后台管理可以在各个app的admin.py文件中进行控制。&lt;/p&gt;
&lt;p&gt;想要对APP应用进行管理，最基本的前提是要先在settings里对其进行注册，就是在INSTALLED_APPS里把APP名添加进去，更多的可以查看文章：&lt;a href=&#34;https://www.django.cn/course/show-10.html&#34;&gt;全局配置settings详解&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;下面我们以一个blog应用来举例，向大家介绍一些常用的自定制admin的方法。如下为blog的models的Article表的内容:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;class Article(models.Model):
    title = models.CharField(&amp;#39;标题&amp;#39;, max_length=70)
    keywords = models.CharField(&amp;#39;文章关键词&amp;#39;, max_length=120, blank=True, null=True)
    excerpt = models.TextField(&amp;#39;摘要&amp;#39;, max_length=200, blank=True)
    category = models.ForeignKey(Category, on_delete=models.CASCADE, verbose_name=&amp;#39;分类&amp;#39;, blank=True, null=True)
    body = models.TextField(&amp;#39;内容&amp;#39;)
    user = models.ForeignKey(Userinfo, on_delete=models.CASCADE, verbose_name=&amp;#39;作者&amp;#39;)
    views = models.PositiveIntegerField(&amp;#39;阅读量&amp;#39;, default=0)
    top = models.IntegerField(choices=[(0, &amp;#39;否&amp;#39;), (1, &amp;#39;是&amp;#39;), ], default=0, verbose_name=&amp;#39;是否推荐&amp;#39;)
    created_time = models.DateTimeField(&amp;#39;发布时间&amp;#39;, auto_now_add=True)
    modified_time = models.DateTimeField(&amp;#39;修改时间&amp;#39;, auto_now=True)
    class Meta:
        verbose_name = &amp;#39;文章&amp;#39;verbose_name_plural = &amp;#39;文章&amp;#39;def __str__(self):
        return self.title
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;一、管理后台注册需要管理的应用&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;只有注册了，我们才能在管理后台看到这个APP应用，才能对其进行管理，这个注册有两种方式：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1、装饰器注册&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;from django.contrib import admin
from .models import Article
  
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
    list_display=(&amp;#39;id&amp;#39;, &amp;#39;category&amp;#39;, &amp;#39;title&amp;#39;, &amp;#39;user&amp;#39;,&amp;#39;views&amp;#39;,&amp;#39;created_time&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;2、注册参数&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>阿里编程规约</title>
      <link>https://leochu.work/blog/tech/engineering/%E9%98%BF%E9%87%8C%E7%BC%96%E7%A8%8B%E8%A7%84%E7%BA%A6/</link>
      <pubDate>Sun, 20 Aug 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/engineering/%E9%98%BF%E9%87%8C%E7%BC%96%E7%A8%8B%E8%A7%84%E7%BA%A6/</guid>
      <description>&lt;p&gt;命名风格&lt;/p&gt;
&lt;ol start=&#34;6&#34;&gt;
&lt;li&gt;
&lt;p&gt;【强制】抽象类命名使用 Abstract 或 Base 开头; 异常类命名使用 Exception 结尾; 测试类 命名以它要测试的类的名称开始，以 Test 结尾。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;【强制】POJO 类中布尔类型变量都不要加 is 前缀，否则部分框架解析会引起序列化错误。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;【强制】包名统一使用小写，点分隔符之间有且仅有一个自然语义的英语单词。包名统一使 用单数形式，但是类名如果有复数含义，类名可以使用复数形式。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;正例: 应用工具类包名为 com.alibaba.ai.util、类名为 MessageUtils&lt;/p&gt;
&lt;ol start=&#34;13&#34;&gt;
&lt;li&gt;【推荐】在常量与变量的命名时，表示类型的名词放在词尾，以提升辨识度。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;正例: startTime / workQueue / nameList / TERMINATED_THREAD_COUNT&lt;/p&gt;
&lt;p&gt;17.【参考】枚举类名带上 Enum 后缀，枚举成员名称需要全大写，单词间用下划线隔开。&lt;/p&gt;
&lt;p&gt;B) 领域模型命名规约&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;数据对象: xxxDO，xxx 即为数据表名。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;数据传输对象: xxxDTO，xxx 为业务领域相关的名称。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;展示对象: xxxVO，xxx 一般为网页名称。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;POJO 是 DO/DTO/BO/VO 的统称，禁止命名成 xxxPOJO。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;常量定义&lt;/p&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;
&lt;p&gt;【推荐】不要使用一个常量类维护所有常量，要按常量功能进行归类，分开维护。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;【推荐】如果变量值仅在一个固定范围内变化用 enum 类型来定义。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;SPRING(1), SUMMER(2), AUTUMN(3), WINTER(4);&lt;/p&gt;
&lt;p&gt;代码格式&lt;/p&gt;
&lt;ol start=&#34;5&#34;&gt;
&lt;li&gt;【强制】采用 4 个空格缩进，禁止使用 tab 字符。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;IDEA 设置 tab 为 4 个空格时，请勿勾选 Use tab character&lt;/p&gt;</description>
    </item>
    <item>
      <title>sql中!=的陷阱</title>
      <link>https://leochu.work/blog/tech/database/sql%E4%B8%AD%E7%9A%84%E9%99%B7%E9%98%B1/</link>
      <pubDate>Sun, 06 Aug 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/database/sql%E4%B8%AD%E7%9A%84%E9%99%B7%E9%98%B1/</guid>
      <description>&lt;p&gt;mysql/SQL server有，clickhouse也有，hive未验证。&lt;/p&gt;
&lt;p&gt;null 值的比较这里另外说下 SQL 里 null 值的比较，任何与 null 值的比较结果，最后都会变成 null，以PostgreSQL为例，如下：select null != null;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;null&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;null&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;null&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;null&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;以上结果都是 null，而不是什么 true 或者 false。另外有些函数是不支持 null 值作为输入参数的，比如count()或者sum()等。&lt;/p&gt;
&lt;p&gt;在写 SQL 条件语句时经常用到 不等于 &lt;code&gt;!=&lt;/code&gt; 的筛选条件。此时要注意此条件会将字段为 &lt;code&gt;Null&lt;/code&gt; 的数据也当做满足不等于的条件而将数据筛选掉。（也就是说会忽略过滤掉为 null 的数据，导致数据不准确）。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;SELECT&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;FROM&lt;/span&gt; A &lt;span style=&#34;color:#66d9ef&#34;&gt;WHERE&lt;/span&gt; B1 &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;不会查出null值&lt;/p&gt;
&lt;p&gt;修改：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;SELECT&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;FROM&lt;/span&gt; A &lt;span style=&#34;color:#66d9ef&#34;&gt;WHERE&lt;/span&gt; B1 &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;OR&lt;/span&gt; B1 &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;SELECT&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;FROM&lt;/span&gt; A &lt;span style=&#34;color:#66d9ef&#34;&gt;WHERE&lt;/span&gt; IFNULL(B1,&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;)  &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;为什么会这样呢？这还得&lt;strong&gt;从 mysql 的底层开始说起，因为 NULL 不是一个「值」，而是「没有值」&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;　　&lt;strong&gt;「没有值」不满足「值不等于1」这个条件，怎么解决可以使用 ifnull() 方法，将 null 转为空字符串，或者这个字段做出判断 加上OR a is null。当然使用 ifnull 相率会更好&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;select null = null返回也是null。null只能用is或is not&lt;/p&gt;</description>
    </item>
    <item>
      <title>mongo操作</title>
      <link>https://leochu.work/blog/tech/database/mongodb%E5%B8%B8%E7%94%A8%E6%93%8D%E4%BD%9C/</link>
      <pubDate>Sun, 23 Jul 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/database/mongodb%E5%B8%B8%E7%94%A8%E6%93%8D%E4%BD%9C/</guid>
      <description>&lt;p&gt;根据日期查询数量&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;db.getCollection(&amp;#34;api_invocation_logs&amp;#34;).find({&amp;#34;createdDate&amp;#34;:{&amp;#34;$gte&amp;#34;:ISODate(&amp;#34;2024-01-09T00:00:00Z&amp;#34;),&amp;#34;$lt&amp;#34;:ISODate(&amp;#34;2024-01-10T00:00:00Z&amp;#34;)}}).count()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;查看某个字段不为空的数据&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;db.getCollection(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;waimao_company_info&amp;#39;&lt;/span&gt;).find(&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;numberOfEmployees&amp;#39;&lt;/span&gt;:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;{$&lt;/span&gt;ne:&lt;span style=&#34;color:#66d9ef&#34;&gt;null&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;}}&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;查看某个表所有字段&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mr &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; db.runCommand(&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;mapreduce&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;waimao_company_info&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;map&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;() &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (var &lt;span style=&#34;color:#66d9ef&#34;&gt;key&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; this) &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            emit(&lt;span style=&#34;color:#66d9ef&#34;&gt;key&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;null&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;}&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;reduce&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;key&lt;/span&gt;, stuff) &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;null&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;}&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;out&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;waimao_company_info&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;_keys&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;}&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;db[mr.&lt;span style=&#34;color:#66d9ef&#34;&gt;result&lt;/span&gt;].&lt;span style=&#34;color:#66d9ef&#34;&gt;distinct&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;_id&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;模糊查询&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;db.getCollection(&amp;#34;rocket&amp;#34;).find(
{emails:/@/}
)
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>es操作</title>
      <link>https://leochu.work/blog/tech/database/elasticsearch%E5%B8%B8%E7%94%A8%E6%93%8D%E4%BD%9C/</link>
      <pubDate>Sun, 09 Jul 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/database/elasticsearch%E5%B8%B8%E7%94%A8%E6%93%8D%E4%BD%9C/</guid>
      <description>&lt;h3 id=&#34;es建表&#34;&gt;ES建表&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;PUT&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;http:&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;//121.46.197.112:9200/cty_test
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;Content-Type:&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;application/json&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;settings&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;number_of_shards&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;number_of_replicas&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;analysis&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;analyzer&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;greek_lowercase_analyzer&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;filter&amp;#34;&lt;/span&gt;: [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;lowercase&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          ],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;custom&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;tokenizer&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;standard&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;mappings&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;cty_test&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;properties&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;dupId&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;text&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;fields&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;keyword&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;ignore_above&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;256&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;keyword&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;text&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;fields&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;keyword&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;ignore_above&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;256&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;keyword&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;supplierId&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;long&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;addTime&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;format&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;yyyy-MM-dd HH:mm:ss&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;date&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;scCountry&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;keyword&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;shipName&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;text&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;manifestQuanityDouble&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;float&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;importerName&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;analyzer&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;greek_lowercase_analyzer&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;text&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;fields&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;keyword&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;ignore_above&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;256&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;keyword&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;tradeType&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;integer&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;arriveDate&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;format&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;yyyy-MM-dd&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;date&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;modeOfTransportation&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;keyword&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;modeoftransPortation&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;text&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;fields&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;keyword&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;ignore_above&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;256&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;keyword&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;weight&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;double&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;es写入数据&#34;&gt;ES写入数据&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;POST&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;http:&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;//121.46.197.112:9200/cty_test/cty_test
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;Content-Type:&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;application/json&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;dupId&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;34324&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;545435&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;supplierId&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#ae81ff&#34;&gt;43636&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;addTime&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2021-02-05 08:08:08&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;scCountry&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;rrr&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;shipName&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;uuu&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;manifestQuanityDouble&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#ae81ff&#34;&gt;55.00&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;importerName&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ccd&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;tradeType&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#ae81ff&#34;&gt;43&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;arriveDate&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2018-09-03&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;weight&amp;#34;&lt;/span&gt; : &lt;span style=&#34;color:#ae81ff&#34;&gt;33.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;查询某列不为空&lt;/p&gt;</description>
    </item>
    <item>
      <title>yarn队列设置</title>
      <link>https://leochu.work/blog/tech/bigdata/yarn%E9%98%9F%E5%88%97%E8%AE%BE%E7%BD%AE/</link>
      <pubDate>Sun, 28 May 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/yarn%E9%98%9F%E5%88%97%E8%AE%BE%E7%BD%AE/</guid>
      <description>&lt;p&gt;在大数据平台运维中，会经常遇到&lt;strong&gt;集群资源争抢的问题&lt;/strong&gt;。因为在公司内部，Hadoop Yarn 集群一般会被多个业务、多个用户同时使用，共享 Yarn 资源。此时，如果不对集群资源做规划和管理的话，那么就会出现 Yarn 的资源被某一个用户提交的 Application（App）占满，而其他用户只能等待；或者也可能会出现集群还有很多剩余资源，但 App 就是无法使用的情况。&lt;/p&gt;
&lt;p&gt;如何解决这个问题呢？此时就需要用到 Hadoop 中提供的&lt;strong&gt;资源调度器&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id=&#34;yarn-多用户资源管理策略&#34;&gt;&lt;strong&gt;Yarn 多用户资源管理策略&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Yarn 提供了可插拔的资源调度算法，用于解决 App 之间资源竞争的问题。在 Yarn 中有三种资源调度器可供选择，即 FIFO Scheduler、Capacity Scheduler、Fair Scheduler，目前使用比较多的是 Fair Scheduler 和 Capacity Scheduler。下面对这三种资源调度器分别进行介绍。&lt;/p&gt;
&lt;h4 id=&#34;1-fifo-scheduler&#34;&gt;&lt;strong&gt;1. FIFO Scheduler&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;在 Hadoop 1.x 系列版本中，默认使用的调度器是 FIFO，它采用队列方式将每个任务按照时间先后顺序进行服务。比如排在最前面的任务需要若干 Map Task 和 Reduce Task，当发现有空闲的服务器节点时就分配给这个任务，直到任务执行完毕。&lt;/p&gt;
&lt;h4 id=&#34;2-capacity-scheduler&#34;&gt;&lt;strong&gt;2. Capacity Scheduler&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;在 Hadoop 2.x/3.x 系列版本中，默认使用的调度器是 Capacity Scheduler（容量调度器），这是一种&lt;strong&gt;多用户、多队列&lt;/strong&gt;的资源调度器。每个队列可以配置资源量，可限制每个用户、每个队列的并发运行作业量，也可限制每个作业使用的内存量；每个用户的作业有优先级，在单个队列中，作业按照先来先服务（实际上是先按照优先级，优先级相同的再按照作业提交时间）的原则进行调度。&lt;/p&gt;
&lt;p&gt;容量资源调度器，支持多队列，&lt;strong&gt;但默认情况下只有 root.default 这一个队列&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;当不同用户提交任务时，任务都会在这个队列里按照先进先出策略执行调度，很明显，单个队列会大大降低多用户的资源使用率。&lt;/p&gt;
&lt;p&gt;因此，要使用容量资源调度，一定要配置多个队列，每个队列可配置一定比率的资源量（CPU、内存）；同时为了防止同一个用户的任务独占队列的所有资源，调度器会对同一个用户提交的任务所占资源量进行限定。&lt;/p&gt;
&lt;p&gt;举个简单的例子，下图是容量调度器中配置好的一个队列树：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;队列树&#34; loading=&#34;lazy&#34; src=&#34;https://cdn.nlark.com/yuque/0/2022/png/21887514/1646927210814-732f7f8b-7cb1-4dc5-b649-f542a504f26b.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;上图通过队列树方式对 Yarn 集群资源做了一个划分，可以看到，在 root 队列下面定义了两个子队列 dev 和 test，分别占 30% 和 70% 的 Yarn 集群资源；而 dev 队列又被分成了 dev1 和 dev2 两个子队列，分别占用 dev 队列 30% 中的 40% 和 60% 的 Yarn 集群资源。&lt;/p&gt;</description>
    </item>
    <item>
      <title>sqoop提交参数解析</title>
      <link>https://leochu.work/blog/tech/bigdata/sqoop%E6%8F%90%E4%BA%A4%E5%8F%82%E6%95%B0%E8%A7%A3%E6%9E%90/</link>
      <pubDate>Sun, 14 May 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/sqoop%E6%8F%90%E4%BA%A4%E5%8F%82%E6%95%B0%E8%A7%A3%E6%9E%90/</guid>
      <description>&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/opt/cloudera/parcels/CDH/lib/sqoop/bin/sqoop import &lt;span style=&#34;color:#ae81ff&#34;&gt;\ &lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--connect jdbc:&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;mysql://ip:port/T_Cloud_Promote&lt;span style=&#34;color:#f92672&#34;&gt;](&lt;/span&gt;mysql://ipport&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\ &lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--username rt_center &lt;span style=&#34;color:#ae81ff&#34;&gt;\ &lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--password pwd&lt;span style=&#34;color:#ae81ff&#34;&gt;\ &lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--query &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;select KeywordID,KeyType,Root,KeywordName,UID,Status,AddDate,UpdateDate,MigrateOID,PromotionStatus,WordType,IsEmphasis,KeywordLength,IsViolate,ViolateWord from T_Cloud_Promote.T_Cloud_User_KeywordLibrary where KeywordID &amp;lt; &lt;/span&gt;$&lt;span style=&#34;color:#e6db74&#34;&gt;[a+10000000] AND KeywordID &amp;gt;= &lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;a&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; AND AddDate != &amp;#39;0000-00-00 00:00:00&amp;#39; AND \$CONDITIONS&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\ &lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--fields-terminated-by &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;\001&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\ &lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--target-dir /tmp/t_cloud_order &lt;span style=&#34;color:#ae81ff&#34;&gt;\ &lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--delete-target-dir &lt;span style=&#34;color:#ae81ff&#34;&gt;\ &lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--hive-import &lt;span style=&#34;color:#ae81ff&#34;&gt;\ &lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--hive-database T_Cloud_Promote &lt;span style=&#34;color:#ae81ff&#34;&gt;\ &lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--hive-table ods_t_cloud_user_keywordlibraryb_tmp_01 &lt;span style=&#34;color:#ae81ff&#34;&gt;\ &lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--null-string &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;\\N&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\ &lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--null-non-string &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;\\N&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\ &lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--hive-drop-import-delims &lt;span style=&#34;color:#ae81ff&#34;&gt;\ &lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--num-mappers &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\ &lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--split-by KeywordID &lt;span style=&#34;color:#ae81ff&#34;&gt;\ &lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--hive-overwrite  
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&amp;ndash;connect&lt;br&gt;
mysql连接&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;ndash;username&lt;br&gt;
用户名&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;ndash;password&lt;br&gt;
密码&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;ndash;query&lt;br&gt;
条件查询语句&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;ndash;fields-terminated-by&lt;br&gt;
分隔符&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;ndash;target-dir&lt;br&gt;
临时存放位置&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;ndash;delete-target-dir \&lt;br&gt;
程序结束删除文件夹&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;ndash;hive-import \&lt;br&gt;
导入到hive&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;ndash;hive-database T_Cloud_Promote \&lt;br&gt;
hive的数据库&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;ndash;hive-table&lt;br&gt;
hive表&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;ndash;null-string &amp;lsquo;\N&amp;rsquo; \&lt;br&gt;
&amp;ndash;null-non-string &amp;lsquo;\N&amp;rsquo; \&lt;br&gt;
转换为hive空&lt;/p&gt;</description>
    </item>
    <item>
      <title>spark提交参数</title>
      <link>https://leochu.work/blog/tech/bigdata/spark%E6%8F%90%E4%BA%A4%E5%8F%82%E6%95%B0/</link>
      <pubDate>Sun, 30 Apr 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/spark%E6%8F%90%E4%BA%A4%E5%8F%82%E6%95%B0/</guid>
      <description>&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;spark-submit --master yarn --conf spark.default.parallelism&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;100&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--deploy-mode cluster --driver-memory 4G --executor-memory 4G &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--num-executors &lt;span style=&#34;color:#ae81ff&#34;&gt;40&lt;/span&gt; --executor-cores &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--conf spark.yarn.executor.memoryOverhead&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;5g &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--class com.lz.hbase.CompanyInfo /tmp/test_langzi/original-spark_hbase01-1.0-SNAPSHOT.jar &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--conf spark.dynamicAllocation.maxExecutors&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;40&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>Spark Thrift Server</title>
      <link>https://leochu.work/blog/tech/bigdata/spark-thrift-server/</link>
      <pubDate>Sun, 16 Apr 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/spark-thrift-server/</guid>
      <description>&lt;h4 id=&#34;文章目录&#34;&gt;文章目录&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#Spark_Thrift_Server_1&#34;&gt;一、Spark Thrift Server 介绍&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#Spark_Thrift_Server_9&#34;&gt;二、部署 Spark Thrift Server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#Spark_Thrift_Server_29&#34;&gt;三、Spark Thrift Server 的架构&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#Spark_Thrift_ServerSQL_40&#34;&gt;四、Spark Thrift Server 如何执行 SQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#HiveServer2_48&#34;&gt;五、和 HiveServer2 的区别&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#Spark_Thrift_Server_58&#34;&gt;Spark Thrift Server 的优点&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#Spark_Thrift_Server_64&#34;&gt;Spark Thrift Server 的缺点&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#_72&#34;&gt;六、结论&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;一spark-thrift-server-介绍&#34;&gt;一、Spark Thrift Server 介绍&lt;/h3&gt;
&lt;p&gt;Spark Thrift Server 是 Spark 社区基于 HiveServer2 实现的一个 Thrift 服务。旨在无缝兼容 HiveServer2。&lt;/p&gt;
&lt;p&gt;因为 Spark Thrift Server 的接口和协议都和 HiveServer2 完全一致，因此我们部署好 Spark Thrift Server 后，可以直接使用 hive 的 beeline 访问 Spark Thrift Server 执行相关语句。&lt;/p&gt;
&lt;p&gt;Spark Thrift Server 的目的也只是取代 HiveServer2，因此它依旧可以和 Hive Metastore 进行交互，获取到 hive 的元数据。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Ranger配置大数据组件</title>
      <link>https://leochu.work/blog/tech/bigdata/ranger%E9%85%8D%E7%BD%AE%E5%A4%A7%E6%95%B0%E6%8D%AE%E7%BB%84%E4%BB%B6/</link>
      <pubDate>Sun, 02 Apr 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/ranger%E9%85%8D%E7%BD%AE%E5%A4%A7%E6%95%B0%E6%8D%AE%E7%BB%84%E4%BB%B6/</guid>
      <description>&lt;p&gt;1.开启ranger-hive ranger-hdfs插件
2.修改hdfs配置
1.开启hdfs认证
hadoop.security.authorization = true&lt;/p&gt;</description>
    </item>
    <item>
      <title>presto</title>
      <link>https://leochu.work/blog/tech/bigdata/presto%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97/</link>
      <pubDate>Sun, 19 Mar 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/presto%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97/</guid>
      <description>&lt;p&gt;presto操作hive&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;presto-cli --server 172.16.98.183:8050 --catalog hive
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>OneData数据仓库架构</title>
      <link>https://leochu.work/blog/tech/bigdata/onedata%E6%95%B0%E6%8D%AE%E4%BB%93%E5%BA%93%E6%9E%B6%E6%9E%84/</link>
      <pubDate>Sun, 05 Mar 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/onedata%E6%95%B0%E6%8D%AE%E4%BB%93%E5%BA%93%E6%9E%B6%E6%9E%84/</guid>
      <description>&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/onedata_%E6%9E%B6%E6%9E%84.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;**1.**&lt;strong&gt;什么是&lt;/strong&gt; &lt;strong&gt;onedata&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;面对爆炸式增长的数据，如何建设高效的数据模型和体系，对这些数据进行有序和有结构地分类组织和存储，避免重复建设和数据不一致性，保证数据的规范性，一直是大数据系统建设不断追求的方向。OneData 即是阿里巴巴内部进行数据整合及管理的方法体系和工具。阿里巴巴的大数据工程师在这一体系下，构建统一、规范、可共享的全域数据体系，避免数据的冗余和重复建设，规避数据烟囱和不一致性，充分发挥阿里巴巴在大数据海量、多样性方面的独特优势。借助这一统一化数据整合及管理的方法体系，我们构建了阿里巴巴的数据公共层，并可以帮助相似的大数据项目快速落地实现。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/onedata_%E6%9E%B6%E6%9E%84.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;**2.**&lt;strong&gt;指导思想&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;阿里巴巴集团数据公共层设计理念遵循维度建模思想，可参考 StarSchema-The Complete Reference 和 The Data Warehouse Toolkit-The Definitive Guide to Dimensional Modeling。数据模型的维度设计主要以维度建模理论为基础，基于维度数据模型总线架构，构建一致性的维度和事实。其核心的实施指导方针如下：&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.w.org/images/core/emoji/17.0.2/svg/26ab.svg&#34;&gt; 首先，要进行充分的业务调研和需求分析。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.w.org/images/core/emoji/17.0.2/svg/26ab.svg&#34;&gt; 其次，进行数据总体架构设计，主要是根据数据域对数据进行划分；按照维度建模理论，构建总线矩阵，抽象出业务过程和维度。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.w.org/images/core/emoji/17.0.2/svg/26ab.svg&#34;&gt; 再次，对报表需求进行抽象整理出相关指标体系，使用 One Data 工具完成指标规范定义和模型设计。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://s.w.org/images/core/emoji/17.0.2/svg/26ab.svg&#34;&gt; 最后，是代码研发和运维。其实施流程主要分为：数据调研、架构设计、规范定义和模型设计。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/onedata_%E6%B5%81%E7%A8%8B.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;**3.**&lt;strong&gt;业务调研&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;业务调研&lt;/strong&gt;：需要确认要规划进数仓的业务领域，以及各业务领域包含的功能模块，以阿里的业务为例，可规划如下矩阵&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/onedata_%E4%B8%9A%E5%8A%A1%E8%B0%83%E7%A0%94.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;需求调研&lt;/strong&gt;：了解需求方关系哪些指标？需要哪些维度、度量？数据是否沉淀到汇总层等。&lt;/p&gt;
&lt;p&gt;可以想象一下，在没有考虑分析师、业务运营人员的数据需求的情况下，根据业务调研建设的数据仓库无疑等于闭门造车。了解了业务系统的业务后并不代表就可以进行实施了，此刻要做的就是收集数据使用者的需求，可以去找分析师、业务运营人员了解他们有什么数据诉求，此时更多的就是报表需求。&lt;/p&gt;
&lt;p&gt;需求调研的途径有两种:一是根据与分析师、业务运营人员的沟通(邮件、IM)获知需求；二是对报表系统中现有的报表进行研究分析。通过需求调研分析后，就清楚数据要做成什么样的。很多时候，都是由具体的数据需求驱动数据仓库团队去了解业务系统的业务数据，这两者并没有严格的先后顺序。&lt;/p&gt;
&lt;p&gt;举例：分析师需要了解大淘宝(淘宝、天猫、天猫国际)一级类目的成交金额。当获知这个需求后，我们要分析根据什么(维度)汇总，以及汇总什么(度量)，这里类目是维度，金额是度量；明细数据和汇总数据应该怎样设计?这是一个公用的报表吗?是需要沉淀到汇总表里面，还是在报表工具中进行汇总?&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/onedata_%E9%9C%80%E6%B1%82%E8%B0%83%E7%A0%94.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;**4.**&lt;strong&gt;架构设计&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4.1 数据域的划分&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;数据域是指面向业务分析，将业务过程或者维度进行抽象的集合，一般数据域和应用系统(功能模块)有联系，可以考虑将同一个功能模块系统的业务过程划分到一个数据域。业务过程可以概括为一个个不可拆分的行为事件，如下单、支付、退款。为保障整个体系的生命力，数据域需要抽象提炼，并且长期维护和更新，但不轻易变动。在划分数据域时，既能涵盖当前所有的业务需求，又能在新业务进入时无影响地被包含进已有的数据域中或者扩展新的数据域。如表所示是功能模块/业务线的业务动作(部分示例)：&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/onedata_%E4%B8%9A%E5%8A%A1%E5%8A%A8%E4%BD%9C.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;根据业务过程进行归纳，可以抽象出如下数据域：&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/onedata_%E6%95%B0%E6%8D%AE%E5%9F%9F.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4.2 构建总线矩阵&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在进行充分的业务调研和需求调研后，就要构建总线矩阵了，需要做两件事情：&lt;/p&gt;
&lt;p&gt;1.明确每个数据域下有哪些业务过程。&lt;/p&gt;
&lt;p&gt;2.业务过程与哪些维度相关，并通过总线矩阵定义每个数据域下的业务过程和维度。&lt;/p&gt;
&lt;p&gt;如下表是供应链管理业务过程示例：&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/onedata_%E4%B8%9A%E5%8A%A1%E6%80%BB%E7%BA%BF%E7%9F%A9%E9%98%B5.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;4.3 规范定义&lt;/p&gt;
&lt;p&gt;规范定义主要定义指标体系，包括原子指标、修饰词、时间周期和派生指标。&lt;/p&gt;
&lt;p&gt;4.4 模型设计&lt;/p&gt;
&lt;p&gt;模型设计主要包括维度及属性的规范定义，维表、明细事实表和汇总事实表的模型设计。&lt;/p&gt;
&lt;p&gt;4.5 架构总结&lt;/p&gt;
&lt;p&gt;One Data 的实施过程是一个高度迭代和动态的过程，一般采用螺旋式实施方法。在总体架构设计完成之后，开始根据数据域进行迭代式模型设计和评审。在架构设计、规范定义和模型设计等模型实施过程中，都会引入评审机制，以确保模型实施过程的正确性。&lt;/p&gt;
&lt;p&gt;**5.**&lt;strong&gt;指标体系搭建&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;5.1 指标体系核心结构&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/onedata_%E6%8C%87%E6%A0%87%E4%BD%93%E7%B3%BB%E6%A0%B8%E5%BF%83%E7%BB%93%E6%9E%84.png&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>left join 谓词下推</title>
      <link>https://leochu.work/blog/tech/bigdata/left-join%E8%B0%93%E8%AF%8D%E4%B8%8B%E6%8E%A8/</link>
      <pubDate>Sun, 19 Feb 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/left-join%E8%B0%93%E8%AF%8D%E4%B8%8B%E6%8E%A8/</guid>
      <description>&lt;p&gt;zzz1&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th style=&#34;text-align: left&#34;&gt;uid&lt;/th&gt;
          &lt;th style=&#34;text-align: left&#34;&gt;is_delete&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;1&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;1&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;2&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;0&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;3&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;0&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;zzz2&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;uid&lt;/th&gt;
          &lt;th style=&#34;text-align: left&#34;&gt;is_delete&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;1&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;0&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;2&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;1&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;3&lt;/td&gt;
          &lt;td style=&#34;text-align: left&#34;&gt;0&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; zzz1 &lt;span style=&#34;color:#66d9ef&#34;&gt;left&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;join&lt;/span&gt; zzz2 &lt;span style=&#34;color:#66d9ef&#34;&gt;on&lt;/span&gt; zzz1.uid &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; zzz2.uid
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; zzz1.is_delete &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;and&lt;/span&gt; zzz2.is_delete &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;结果:
3       0       3       0&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; zzz1 &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; zzz1.is_delete &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;) z1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;left&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;join&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; zzz2 &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; zzz2.is_delete &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;) z2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;on&lt;/span&gt; z1.uid &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; z2.uid
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;结果:
2       0       NULL    NULL
3       0       3       0&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; zzz1 &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; zzz1.is_delete &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;) z1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;left&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;join&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; zzz2 &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; zzz2.is_delete &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;) z2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;on&lt;/span&gt; z1.uid &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; z2.uid &lt;span style=&#34;color:#66d9ef&#34;&gt;where&lt;/span&gt; z2.uid &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;not&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;结果:
3       0       3       0&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kerberos入门</title>
      <link>https://leochu.work/blog/tech/bigdata/kerberos%E5%85%A5%E9%97%A8/</link>
      <pubDate>Sun, 05 Feb 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/kerberos%E5%85%A5%E9%97%A8/</guid>
      <description>&lt;h2 id=&#34;1kerberos是什么&#34;&gt;1. Kerberos是什么&lt;/h2&gt;
&lt;p&gt;Kerberos在古希腊神话中是指：一只有三个头的狗。这条狗守护在地狱之门外，防止活人闯入。&lt;/p&gt;
&lt;p&gt;Kerberos是一个用于鉴定身份的协议，它采用对称密钥加密。&lt;/p&gt;
&lt;p&gt;在我们的CDH平台中，常用来作为一种安全验证，只有经过kerberos认证后的用户才可以访问大数据集群的服务。&lt;/p&gt;
&lt;h2 id=&#34;2kerberos中的一些概念&#34;&gt;2.Kerberos中的一些概念&lt;/h2&gt;
&lt;p&gt;KDC(key distribution center): kerberos的认证中心，用来鉴别用户的身份的。想访问带kerberos的服务，得先过这个。&lt;/p&gt;
&lt;p&gt;Principal: kerberos中账户的概念，用户会以这个账户来被KDC认证。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;一个Principal由三个部分组成：primary, instance以及realm，其组成形式为primary/instance@realm。

primary : 可以是OS中的username，也可以是service name；
instance : 用于区分属于同一个user或者service的多个principals，该项为optional；
realm : 类似于DNS中的domain，定义了一组principals

举个栗子：hive/hive@ZHENDAO.COM    kafka/kafka@ZHENDAO.COM
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;KeyTab: 以文件的形式呈现，存储了一个或多个Principal的长期的key，用途和密码类似，用于kerberos认证登录；&lt;/p&gt;
&lt;p&gt;其存在的意义在于让用户不需要明文的存储密码，和程序交互时不需要人为交互来输入密码。
&lt;img alt=&#34;Pasted image 20230327112709.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230327112709.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;TGT: 用户使用principal在KDC中进行认证后，KDC会返回给客户一个TGT，TGT会有过期时间。
&lt;img alt=&#34;Pasted image 20230327112731.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230327112731.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;Ticket：用户访问具体Server时，KDC会进行一次加密操作，返回给用户一张对应server的门票。&lt;/p&gt;
&lt;h2 id=&#34;3kerberos基本使用&#34;&gt;3.Kerberos基本使用&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;kerberos管理员创建一个principal, 并生成对应的keytab文件  → 注册一个kerberos的账号，并配置了免密登录&lt;/li&gt;
&lt;li&gt;拿着keytab去KDC中进行账户的认证 → kinit  -kt  /var/lib/hive/hive.keytab  &lt;a href=&#34;mailto:hive/hive@ZHENDAO.COM&#34;&gt;hive/hive@ZHENDAO.COM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;KDC返回一个这个principal对应的TGT文件 → 默认存放在linux的 /tmp 目录下&lt;/li&gt;
&lt;li&gt;客户拿着TGT去过带有kerberos的服务端APP&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;4kerberos认证原理&#34;&gt;4.Kerberos认证原理&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;客户拿着principal去KDC中进行认证的时候，kerberos会检查其库中是否有对应的principal，如果有的话，返回一个TGT。&lt;/li&gt;
&lt;li&gt;客户拿着TGT向带有kerberos的服务端app发起请求时，请求会先发到KDC。&lt;/li&gt;
&lt;li&gt;KDC会拿着客户的master key（客户密码的hash）和服务端的master key（比如说hive server的master key）进行加密操作，并返回给客户一个对应hive  server的ticket。&lt;/li&gt;
&lt;li&gt;客户拿着加密后的ticket,去请求hive服务的时候，hive会对ticket进行一个验证。验证通过即可访问hive&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;5举个栗子kafka认证过程&#34;&gt;5.举个栗子：KAFKA认证过程&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;kafka producer拿着principal向KDC认证身份，通过则拿到KDC返回的TGT  &amp;lt;这是第一次认证，就好比在游乐园的门口，做一次验票操作&amp;gt;&lt;/li&gt;
&lt;li&gt;producer拿着TGT向KDC请求kafka的服务，KDC验证TGT，看该账号能不能使用kafka，如果可以使用，那么进行加密，并返回一个ticket给producer &amp;lt;这是第二次认证，就好比你想玩游乐园中的具体项目，得看看你买的门票有没有这个资格玩VIP项目&amp;gt;&lt;/li&gt;
&lt;li&gt;producer拿着ticket和kafka server尝试建立连接，kafka server会使用server的master key对ticket进行一次解密操作，来验证producer的身份，通过则建立连接 &amp;lt;玩上具体的项目了&amp;gt;&lt;/li&gt;
&lt;/ol&gt;</description>
    </item>
    <item>
      <title>kafka在zk中的目录结构</title>
      <link>https://leochu.work/blog/tech/bigdata/kafka%E5%9C%A8zk%E4%B8%AD%E7%9A%84%E7%9B%AE%E5%BD%95%E7%BB%93%E6%9E%84/</link>
      <pubDate>Sun, 22 Jan 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/kafka%E5%9C%A8zk%E4%B8%AD%E7%9A%84%E7%9B%AE%E5%BD%95%E7%BB%93%E6%9E%84/</guid>
      <description>&lt;p&gt;&lt;img alt=&#34;kafkaInZK&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/kafkaInZK.png&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kafka数据导入ClickHouse</title>
      <link>https://leochu.work/blog/tech/bigdata/kafka%E6%95%B0%E6%8D%AE%E5%AF%BC%E5%85%A5clickhouse/</link>
      <pubDate>Sun, 08 Jan 2023 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/kafka%E6%95%B0%E6%8D%AE%E5%AF%BC%E5%85%A5clickhouse/</guid>
      <description>&lt;h2 id=&#34;1kafka中数据导入clickhouse的标准流程&#34;&gt;1.Kafka中数据导入ClickHouse的标准流程&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;在ClickHouse中建立Kafka Engine 外表，作为Kafka数据源的一个接口&lt;/li&gt;
&lt;li&gt;在ClickHouse中创建普通表(通常是MergeTree系列）存储Kafka中的数据&lt;/li&gt;
&lt;li&gt;在ClickHouse中创建Materialized View, 监听Kafka中的数据，并将数据写入ClickHouse存储表中&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上述三个步骤，就可以将Kafka中的数据导入到ClickHouse集群中。&lt;/p&gt;
&lt;h2 id=&#34;2-kafka数据导入clickhouse详细步骤&#34;&gt;2. Kafka数据导入ClickHouse详细步骤&lt;/h2&gt;
&lt;p&gt;ClickHouse 提供了Kafka Engine 作为访问Kafka集群的一个接口（数据流）。有了这个接口后，导入数据就很方便了，具体步骤如下：&lt;/p&gt;
&lt;h3 id=&#34;步骤1创建kafka-engine&#34;&gt;步骤1：创建Kafka Engine&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;CREATE&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;TABLE&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;source&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;`&lt;/span&gt;ts&lt;span style=&#34;color:#f92672&#34;&gt;`&lt;/span&gt; DateTime, 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;`&lt;/span&gt;tag&lt;span style=&#34;color:#f92672&#34;&gt;`&lt;/span&gt; String, 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;`&lt;/span&gt;message&lt;span style=&#34;color:#f92672&#34;&gt;`&lt;/span&gt; String
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ENGINE &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Kafka()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SETTINGS kafka_broker_list &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;172.19.0.47:9092&amp;#39;&lt;/span&gt;, 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         kafka_topic_list &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;tag&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         kafka_group_name &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;clickhouse&amp;#39;&lt;/span&gt;, 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         kafka_format &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;JSONEachRow&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         kafka_skip_broken_messages &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         kafka_num_consumers &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;必选参数：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;kafkabrokerlist: 这里填写Kafka服务的broker列表，用逗号分隔&lt;/li&gt;
&lt;li&gt;kafkatopiclist: 这里填写Kafka topic,多个topic用逗号分隔&lt;/li&gt;
&lt;li&gt;kafkagroupname：这里填写消费者group名称 &lt;/li&gt;
&lt;li&gt;kafkaformat__:Kafka数据格式, ClickHouse支持的Format, 详见这里 可选参数： &lt;/li&gt;
&lt;li&gt;kafkaskipbrokenmessages：填写大于等于0的整数，表示忽略解析异常的Kafka数据的条数。如果出现了N条异常后，后台线程结束，Materialized View会被重新安排后台线程去监听数据 &lt;/li&gt;
&lt;li&gt;kafkanumconsumers_: 单个Kafka Engine 的消费者数量，通过增加该参数，可以提高消费数据吞吐，但总数不应超过对应topic的partitions总数&lt;/li&gt;
&lt;li&gt;kafkarowdelimiter: 消息分隔符  &lt;/li&gt;
&lt;li&gt;kafkaschema__:对于kafkaformat需要schema定义的时候，其schema由该参数确定&lt;/li&gt;
&lt;li&gt;kafkamaxblocksize: 该参数控制Kafka数据写入目标表的Block大小，超过该数值后，就将数据刷盘。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;步骤2创建存储kafka数据的目标表该表就是最终存储kafka数据-本文中采用mergetree来存储kafka数据&#34;&gt;步骤2：创建存储Kafka数据的目标表，该表就是最终存储Kafka数据 本文中，采用MergeTree来存储Kafka数据：&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;CREATE&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;TABLE&lt;/span&gt; target
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;`&lt;/span&gt;ts&lt;span style=&#34;color:#f92672&#34;&gt;`&lt;/span&gt; DateTime, 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;`&lt;/span&gt;tag&lt;span style=&#34;color:#f92672&#34;&gt;`&lt;/span&gt; String
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ENGINE &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; MergeTree()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PARTITION &lt;span style=&#34;color:#66d9ef&#34;&gt;BY&lt;/span&gt; toYYYYMM(ts)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;ORDER&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;BY&lt;/span&gt; tag
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;步骤3创建metrialized-view-抓取数据&#34;&gt;步骤3：创建Metrialized View 抓取数据&lt;/h3&gt;
&lt;p&gt;本文中，采用如下语句创建MV:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kafka 中的控制器组件</title>
      <link>https://leochu.work/blog/tech/bigdata/kafka%E6%8E%A7%E5%88%B6%E5%99%A8%E7%BB%84%E4%BB%B6/</link>
      <pubDate>Sun, 25 Dec 2022 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/kafka%E6%8E%A7%E5%88%B6%E5%99%A8%E7%BB%84%E4%BB%B6/</guid>
      <description>&lt;p&gt;&lt;strong&gt;控制器组件（Controller），是 Apache Kafka 的核心组件。它的主要作用是在 Apache ZooKeeper 的帮助下管理和协调整个 Kafka 集群&lt;/strong&gt;。集群中任意一台 Broker 都能充当控制器的角色，但是，在运行过程中，只能有一个 Broker 成为控制器，行使其管理和协调的职责。换句话说，每个正常运转的 Kafka 集群，在任意时刻都有且只有一个控制器。官网上有个名为 activeController 的 JMX 指标，可以帮助我们实时监控控制器的存活状态。这个 JMX 指标非常关键，你在实际运维操作过程中，一定要实时查看这个指标的值。下面，我们就来详细说说控制器的原理和内部运行机制。&lt;/p&gt;
&lt;p&gt;在开始之前，我先简单介绍一下 Apache ZooKeeper 框架。要知道，&lt;strong&gt;控制器是重度依赖 ZooKeeper&lt;/strong&gt; 的，因此，我们有必要花一些时间学习下 ZooKeeper 是做什么的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Apache ZooKeeper 是一个提供高可靠性的分布式协调服务框架&lt;/strong&gt;。它使用的数据模型类似于文件系统的树形结构，根目录也是以 “/” 开始。该结构上的每个节点被称为 znode，用来保存一些元数据协调信息。&lt;/p&gt;
&lt;p&gt;如果以 znode 持久性来划分，&lt;strong&gt;znode 可分为持久性 znode 和临时 znode&lt;/strong&gt;。持久性 znode 不会因为 ZooKeeper 集群重启而消失，==而临时 znode 则与创建该 znode 的 ZooKeeper 会话绑定，一旦会话结束，该节点会被自动删除==。&lt;/p&gt;
&lt;p&gt;==ZooKeeper 赋予客户端监控 znode 变更的能力，即所谓的 Watch 通知功能。一旦 znode 节点被创建、删除，子节点数量发生变化，抑或是 znode 所存的数据本身变更，ZooKeeper 会通过节点变更监听器 (ChangeHandler) 的方式显式通知客户端。==&lt;/p&gt;
&lt;p&gt;依托于这些功能，ZooKeeper 常被用来实现&lt;strong&gt;集群成员管理、分布式锁、领导者选举&lt;/strong&gt;等功能。==Kafka 控制器大量使用 Watch 功能实现对集群的协调管理==。我们一起来看一张图片，它展示的是 Kafka 在 ZooKeeper 中创建的 znode 分布。你不用了解每个 znode 的作用，但你可以大致体会下 Kafka 对 ZooKeeper 的依赖。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kafka 常见的脚本汇总</title>
      <link>https://leochu.work/blog/tech/bigdata/kafka%E5%B8%B8%E7%94%A8%E8%84%9A%E6%9C%AC%E6%B1%87%E6%80%BB/</link>
      <pubDate>Sun, 11 Dec 2022 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/kafka%E5%B8%B8%E7%94%A8%E8%84%9A%E6%9C%AC%E6%B1%87%E6%80%BB/</guid>
      <description>&lt;h2 id=&#34;命令行脚本概览&#34;&gt;命令行脚本概览&lt;/h2&gt;
&lt;hr&gt;
&lt;p&gt;Kafka 默认提供了很多个命令行脚本，用于实现各种各样的功能和运维管理。今天我以 2.2 版本为例，详细地盘点下这些命令行工具。下图展示了 2.2 版本提供的所有命令行脚本。&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20230328115823.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230328115823.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;从图中我们可以知道，2.2 版本总共提供了 30 个 SHELL 脚本。图中的 windows 实际上是个子目录，里面保存了 Windows 平台下的 BAT 批处理文件。其他的. sh 文件则是 Linux 平台下的标准 SHELL 脚本。&lt;/p&gt;
&lt;p&gt;默认情况下，不加任何参数或携带 &amp;ndash;help 运行 SHELL 文件，会得到该脚本的使用方法说明。下面这张图片展示了 kafka-log-dirs 脚本的调用方法。&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20230328115849.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230328115849.png&#34;&gt;
有了这些基础的了解，我来逐一地说明这些脚本的用途，然后再给你详细地介绍一些常见的脚本。&lt;/p&gt;
&lt;p&gt;我们先来说说 connect-standalone 和 connect-distributed 两个脚本。这两个脚本是 Kafka Connect 组件的启动脚本。在专栏第 4 讲谈到 Kafka 生态时，我曾说过社区提供了 Kafka Connect 组件，用于实现 Kafka 与外部世界系统之间的数据传输。Kafka Connect 支持单节点的 Standalone 模式，也支持多节点的 Distributed 模式。这两个脚本分别是这两种模式下的启动脚本。鉴于 Kafka Connect 不在我们的讨论范围之内，我就不展开讲了。&lt;/p&gt;
&lt;p&gt;接下来是 kafka-acls 脚本。它是用于设置 Kafka 权限的，比如设置哪些用户可以访问 Kafka 的哪些主题之类的权限。在专栏后面，我会专门来讲 Kafka 安全设置的内容，到时候我们再细聊这个脚本。&lt;/p&gt;</description>
    </item>
    <item>
      <title>impala配置调优</title>
      <link>https://leochu.work/blog/tech/bigdata/impala%E9%85%8D%E7%BD%AE%E8%B0%83%E4%BC%98/</link>
      <pubDate>Sun, 27 Nov 2022 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/impala%E9%85%8D%E7%BD%AE%E8%B0%83%E4%BC%98/</guid>
      <description>&lt;h6 id=&#34;impala-daemon-命令行参数高级配置代码段安全阀&#34;&gt;&lt;strong&gt;Impala Daemon 命令行参数高级配置代码段（安全阀）&lt;/strong&gt;&lt;/h6&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;-use_local_tz_for_unix_timestamp_conversions=true
-convert_legacy_hive_parquet_utc_timestamps=true
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在hive中，一个中文字符长度为1&lt;/p&gt;
&lt;p&gt;在impala中，一个中文字符长度为3&lt;/p&gt;</description>
    </item>
    <item>
      <title>Hive注册udf</title>
      <link>https://leochu.work/blog/tech/bigdata/hive%E6%B3%A8%E5%86%8Cudf/</link>
      <pubDate>Sun, 13 Nov 2022 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/hive%E6%B3%A8%E5%86%8Cudf/</guid>
      <description>&lt;h4 id=&#34;1创建临时函数&#34;&gt;1.创建临时函数&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hive&amp;gt; add jar /home/hadoop/bigdata_udf.jar;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hive&amp;gt; create temporary &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; isContains100 as &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;com.xx.hive.udf.hm2.IsContains100&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--验证
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hive&amp;gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; isContains100&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;t.col1&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; from t limit 10;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hive&amp;gt; drop temporary &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; isContains100;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;2创建永久函数&#34;&gt;2.创建永久函数&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hadoop fs -put /opt/bigdata_udf.jar /udf
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hive&amp;gt; create &lt;span style=&#34;color:#66d9ef&#34;&gt;function&lt;/span&gt; default.url_decode as &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;com.xx.udf.DecodeURL&amp;#39;&lt;/span&gt; using jar &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;hdfs:///udf/bigdata_udf.jar&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--验证
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hive&amp;gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; default.url_decode&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;t.col1&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; from t limit 10;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;注意注册永久函数必须使用hdfs路径不可使用本地路径&#34;&gt;注意:注册永久函数必须使用hdfs路径,不可使用本地路径&lt;/h4&gt;</description>
    </item>
    <item>
      <title>Hive映射HBase数据源</title>
      <link>https://leochu.work/blog/tech/bigdata/hive%E6%98%A0%E5%B0%84hbase%E6%95%B0%E6%8D%AE%E6%BA%90/</link>
      <pubDate>Sun, 30 Oct 2022 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/hive%E6%98%A0%E5%B0%84hbase%E6%95%B0%E6%8D%AE%E6%BA%90/</guid>
      <description>&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;CREATE&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;EXTERNAL&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;TABLE&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;`&lt;/span&gt;mongodb_dingtalk.hbasetohive_patent&lt;span style=&#34;color:#f92672&#34;&gt;`&lt;/span&gt;(  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;key&lt;/span&gt; String,  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;abstracts String,  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;address String)  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;STORED &lt;span style=&#34;color:#66d9ef&#34;&gt;BY&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;org.apache.hadoop.hive.hbase.HBaseStorageHandler&amp;#39;&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;WITH&lt;/span&gt; SERDEPROPERTIES (&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;hbase.columns.mapping&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;:key,info:abstracts,info:address&amp;#34;&lt;/span&gt;)  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;TBLPROPERTIES(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;[hbase.table.name](http://hbase.table.name/)&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;dingtalk:patent&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;仅从HBase拉取数据使用，禁止利用此种方式往HBase写数据&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;数据拉出时拉出hbase中数据对应当前版本的时间戳&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;create&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;external&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;table&lt;/span&gt; ods.ods_zxk_hbase_wechat_public_account_mapping(  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;id string &lt;span style=&#34;color:#66d9ef&#34;&gt;comment&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;需要拆分的key&amp;#39;&lt;/span&gt;,  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ts &lt;span style=&#34;color:#66d9ef&#34;&gt;timestamp&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;comment&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;数据标识符，用来跟新数据做去重&amp;#39;&lt;/span&gt;)  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;comment&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;高级搜索有无微信公众号&amp;#39;&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;STORED &lt;span style=&#34;color:#66d9ef&#34;&gt;BY&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;org.apache.hadoop.hive.hbase.HBaseStorageHandler&amp;#39;&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;WITH&lt;/span&gt; SERDEPROPERTIES (&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;hbase.columns.mapping&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;:key,:timestamp&amp;#39;&lt;/span&gt;)  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;TBLPROPERTIES(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;[hbase.table.name](http://hbase.table.name/)&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;dingtalk:wechat_public_account&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>hive映射es</title>
      <link>https://leochu.work/blog/tech/bigdata/hive%E6%98%A0%E5%B0%84elasticsearch/</link>
      <pubDate>Sun, 16 Oct 2022 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/hive%E6%98%A0%E5%B0%84elasticsearch/</guid>
      <description>&lt;h3 id=&#34;一-hive导入es&#34;&gt;一 hive导入es&lt;/h3&gt;
&lt;h4 id=&#34;1-创建hive-es映射表&#34;&gt;1 创建hive-es映射表&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;CREATE&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;EXTERNAL&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;TABLE&lt;/span&gt; hive_es.re_run_test2(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;id STRING
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;,test STRING)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;STORED &lt;span style=&#34;color:#66d9ef&#34;&gt;BY&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;org.elasticsearch.hadoop.hive.EsStorageHandler&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;TBLPROPERTIES(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;es.resource&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;re_run_test2/test&amp;#39;&lt;/span&gt;, 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;es.nodes&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;172.16.98.113,172.16.98.149,172.16.98.150,172.16.98.151,172.16.98.152&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;es.port&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;9200&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;es.mapping.id&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;id&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;注&#34;&gt;注：&lt;/h3&gt;
&lt;h3 id=&#34;1&#34;&gt;1.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;es.resource对应es中的index/type
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;2&#34;&gt;2.&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;1.es.mapping.names为hive和es字段名映射关系。
2.如果hive表和es表字段名完全一致，可以省略此参数。
3.hive中字段名不区分大小写，元数据寸的全是小写；es中字段大小写敏感，如果es中字段名出现大写，需认真填写。
4.es中_id为自动生成，如若需要覆盖，需加参数&amp;#39;es.mapping.id&amp;#39;=&amp;#39;id&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;&lt;/h3&gt;
&lt;h4 id=&#34;2-先导入es映射表相关jar包&#34;&gt;2 先导入es映射表相关jar包&lt;/h4&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;add jar /opt/cloudera/parcels/CDH-6.3.2-1.cdh6.3.2.p0.1605554/lib/hive/auxlib/elasticsearch-hadoop-6.3.0.jar;
add jar /data/jar/httpclient-4.5.5.jar;
add jar /data/jar/org.apache.commons.httpclient.jar;
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&#34;3-向映射表insert数据&#34;&gt;3 向映射表insert数据&lt;/h4&gt;
&lt;h3 id=&#34;二-es导入hive&#34;&gt;二 es导入hive&lt;/h3&gt;
&lt;h4 id=&#34;1-建hive映射表&#34;&gt;1 建hive映射表&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;CREATE&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;EXTERNAL&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;TABLE&lt;/span&gt; hive_es.cty_test5(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;addTime string
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;STORED &lt;span style=&#34;color:#66d9ef&#34;&gt;BY&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;org.elasticsearch.hadoop.hive.EsStorageHandler&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;TBLPROPERTIES(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;es.resource&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;cty_test/cty_test&amp;#39;&lt;/span&gt;, 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;es.nodes&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;172.16.98.113,172.16.98.149,172.16.98.150,172.16.98.151,172.16.98.152&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;es.port&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;9200&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;es.mapping.names&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;addTime:addTime&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;es.mapping.date.rich&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;false&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;es.index.auto.create&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;false&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h5 id=&#34;注意hive表数据类型要和es一致除了es的date要转成hive的string同时要加参数esmappingdaterichfalse否则查询会报错&#34;&gt;注意，hive表数据类型要和es一致，除了es的date要转成hive的string，同时要加参数&amp;rsquo;es.mapping.date.rich&amp;rsquo;=&amp;lsquo;false&amp;rsquo;,否则查询会报错.&lt;/h5&gt;
&lt;h4 id=&#34;2-通过映射表向其他表insert&#34;&gt;2 通过映射表向其他表insert&lt;/h4&gt;
&lt;h3 id=&#34;参考&#34;&gt;参考：&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.cnblogs.com/koushr/p/9505435.html&#34;&gt;https://www.cnblogs.com/koushr/p/9505435.html&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>hive设置spark参数</title>
      <link>https://leochu.work/blog/tech/bigdata/hive%E8%AE%BE%E7%BD%AEspark%E5%8F%82%E6%95%B0/</link>
      <pubDate>Sun, 02 Oct 2022 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/hive%E8%AE%BE%E7%BD%AEspark%E5%8F%82%E6%95%B0/</guid>
      <description>&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;set spark.master&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;yarn-cluster;          &lt;span style=&#34;color:#75715e&#34;&gt;#设置spark提交模式&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;set hive.execution.engine&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;spark;         &lt;span style=&#34;color:#75715e&#34;&gt;#设置计算引擎&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;set spark.yarn.queue&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;queue_name;      &lt;span style=&#34;color:#75715e&#34;&gt;#设置作业提交队列&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;set spark.app.name&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;job_name;         &lt;span style=&#34;color:#75715e&#34;&gt;#设置作业名称&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;set spark.executor.instances&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;20;         &lt;span style=&#34;color:#75715e&#34;&gt;#设置执行器个数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;set spark.executor.cores&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;4;            &lt;span style=&#34;color:#75715e&#34;&gt;#设置执行器计算核个数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;set spark.executor.memory&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;8g;         &lt;span style=&#34;color:#75715e&#34;&gt;#设置执行器内存&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;set mapred.reduce.tasks&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;600;           &lt;span style=&#34;color:#75715e&#34;&gt;#设置任务并行度&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;set spark.yarn.executor.memoryOverhead&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;2048;   &lt;span style=&#34;color:#75715e&#34;&gt;#设置每个executor的jvm堆外内存&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;set spark.memory.fraction&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;0.8;          &lt;span style=&#34;color:#75715e&#34;&gt;#设置内存比例(spark2.0+)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;set spark.serializer&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;org.apache.serializer.KyroSerializer;  &lt;span style=&#34;color:#75715e&#34;&gt;#设置对象序列化方式&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>Hive调优大全</title>
      <link>https://leochu.work/blog/tech/bigdata/hive%E8%B0%83%E4%BC%98%E5%A4%A7%E5%85%A8/</link>
      <pubDate>Sun, 18 Sep 2022 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/hive%E8%B0%83%E4%BC%98%E5%A4%A7%E5%85%A8/</guid>
      <description>&lt;h1 id=&#34;调优具体细节&#34;&gt;调优具体细节&lt;/h1&gt;
&lt;h2 id=&#34;hive建表设计层面&#34;&gt;Hive建表设计层面&lt;/h2&gt;
&lt;p&gt;Hive 的建表设计层面调优，主要讲的怎么样合理的组织数据，方便后续的高效计算。比如建表的类型，文件存储格式，是否压缩等等。&lt;/p&gt;
&lt;h3 id=&#34;利用分区表优化&#34;&gt;利用分区表优化&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;关于 Hive 的表的类型有哪些？
1、分区表  
2、分桶表
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;分区表 是在某一个或者几个维度上对数据进行分类存储，一个分区对应一个目录。如果筛选条件里有分区字段，那么 Hive 只需要遍历对应分区目录下的文件即可，不需要遍历全局数据，使得处理的数据量大大减少，从而提高查询效率。&lt;/p&gt;
&lt;p&gt;也就是说：&lt;strong&gt;当一个 Hive 表的查询大多数情况下，会根据某一个字段进行筛选时，那么非常适合创建为分区表，该字段即为分区字段。&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;select1:  select ....  where country = &amp;#34;china&amp;#34;
select2:  select ....  where country = &amp;#34;china&amp;#34;
select3:  select ....  where country = &amp;#34;china&amp;#34;
select4:  select ....  where country = &amp;#34;china&amp;#34;
.....
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;分门别类：这个city字段的每个值，就单独形成为一个分区。其实每个分区就对应带HDFS的一个目录&lt;/p&gt;
&lt;p&gt;在创建表时通过启用 &lt;code&gt;partitioned by&lt;/code&gt; 实现，用来 partition 的维度并不是实际数据的某一列，具体分区的标志是由插入内容时给定的。当要查询某一分区的内容时可以采用 where 语句，形似 &lt;code&gt;where tablename.partition_column = a&lt;/code&gt; 来实现。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1、创建含分区的表：&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;CREATE&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;TABLE&lt;/span&gt; page_view(viewTime INT, userid BIGINT,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                       page_url STRING, referrer_url STRING,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                       ip STRING &lt;span style=&#34;color:#66d9ef&#34;&gt;COMMENT&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;IP Address of the User&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PARTITIONED &lt;span style=&#34;color:#66d9ef&#34;&gt;BY&lt;/span&gt;(date STRING, country STRING)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;ROW&lt;/span&gt; FORMAT DELIMITED FIELDS TERMINATED &lt;span style=&#34;color:#66d9ef&#34;&gt;BY&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;1&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;STORED &lt;span style=&#34;color:#66d9ef&#34;&gt;AS&lt;/span&gt; TEXTFILE;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;2、载入内容，并指定分区标志：&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Hive常用参数语句</title>
      <link>https://leochu.work/blog/tech/bigdata/hive%E5%B8%B8%E7%94%A8%E5%8F%82%E6%95%B0%E8%AF%AD%E5%8F%A5/</link>
      <pubDate>Sun, 04 Sep 2022 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/hive%E5%B8%B8%E7%94%A8%E5%8F%82%E6%95%B0%E8%AF%AD%E5%8F%A5/</guid>
      <description>&lt;h4 id=&#34;1动态分区&#34;&gt;1.动态分区&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;SET&lt;/span&gt; hive.&lt;span style=&#34;color:#66d9ef&#34;&gt;exec&lt;/span&gt;.&lt;span style=&#34;color:#66d9ef&#34;&gt;dynamic&lt;/span&gt;.partition&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;SET&lt;/span&gt; hive.&lt;span style=&#34;color:#66d9ef&#34;&gt;exec&lt;/span&gt;.&lt;span style=&#34;color:#66d9ef&#34;&gt;dynamic&lt;/span&gt;.partition.&lt;span style=&#34;color:#66d9ef&#34;&gt;mode&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;nonstrict;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;SET&lt;/span&gt; hive.&lt;span style=&#34;color:#66d9ef&#34;&gt;exec&lt;/span&gt;.&lt;span style=&#34;color:#66d9ef&#34;&gt;max&lt;/span&gt;.&lt;span style=&#34;color:#66d9ef&#34;&gt;dynamic&lt;/span&gt;.partitions&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;100000&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;SET&lt;/span&gt; hive.&lt;span style=&#34;color:#66d9ef&#34;&gt;exec&lt;/span&gt;.&lt;span style=&#34;color:#66d9ef&#34;&gt;max&lt;/span&gt;.&lt;span style=&#34;color:#66d9ef&#34;&gt;dynamic&lt;/span&gt;.partitions.pernode&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;100000&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;SET&lt;/span&gt; hive.&lt;span style=&#34;color:#66d9ef&#34;&gt;exec&lt;/span&gt;.&lt;span style=&#34;color:#66d9ef&#34;&gt;max&lt;/span&gt;.created.files&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;100000&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;2union-all并发执行&#34;&gt;2.union all并发执行&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;--在使用union all的时候，系统资源足够的情况下，为了加快hive处理速度，可以设置如下参数实现并发执行
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;set&lt;/span&gt; mapred.job.priority&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;VERY_HIGH;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;set&lt;/span&gt; hive.&lt;span style=&#34;color:#66d9ef&#34;&gt;exec&lt;/span&gt;.parallel&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;3设置map-reduce个数&#34;&gt;3.设置map reduce个数&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 设置map capacity
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;set&lt;/span&gt; mapred.job.&lt;span style=&#34;color:#66d9ef&#34;&gt;map&lt;/span&gt;.capacity&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;2000&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;set&lt;/span&gt; mapred.job.reduce.capacity&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;2000&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 设置每个reduce的大小
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;set&lt;/span&gt; hive.&lt;span style=&#34;color:#66d9ef&#34;&gt;exec&lt;/span&gt;.reducers.bytes.per.reducer&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;500000000&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 直接设置个数
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;set&lt;/span&gt; mapred.reduce.tasks &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;15&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;4文件合并&#34;&gt;4.文件合并&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 设置文件合并
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;set&lt;/span&gt; abaci.&lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt;.dag.job&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;set&lt;/span&gt; hive.merge.mapredfiles&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;set&lt;/span&gt; mapred.combine.&lt;span style=&#34;color:#66d9ef&#34;&gt;input&lt;/span&gt;.format.&lt;span style=&#34;color:#66d9ef&#34;&gt;local&lt;/span&gt;.&lt;span style=&#34;color:#66d9ef&#34;&gt;only&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;set&lt;/span&gt; hive.merge.smallfiles.avgsize&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;100000000&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 在map only的情况下，如上的参数如果没有生效，可以设置如下
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 在HQL的最外层增加distribute by rand()
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;select&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; XXX distribute &lt;span style=&#34;color:#66d9ef&#34;&gt;by&lt;/span&gt; rand()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;5设置任务名称&#34;&gt;5.设置任务名称&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;-- 设置名称
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;set&lt;/span&gt; mapred.job.name&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;${&lt;/span&gt;my_job&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;}&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;6设置引擎和指定队列&#34;&gt;6.设置引擎和指定队列&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;set&lt;/span&gt; hive.execution.engine&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;mr;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;set&lt;/span&gt; mapreduce.job.queuename&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;bigdata;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>Hive-mongo导入导出</title>
      <link>https://leochu.work/blog/tech/bigdata/hive-mongo%E5%AF%BC%E5%85%A5%E5%AF%BC%E5%87%BA/</link>
      <pubDate>Sun, 21 Aug 2022 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/hive-mongo%E5%AF%BC%E5%85%A5%E5%AF%BC%E5%87%BA/</guid>
      <description>&lt;h4 id=&#34;1mongodb拉出到hive&#34;&gt;1.MongoDB拉出到hive&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;#&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;导入&lt;/span&gt;mongodb的包到hadoop
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;add&lt;/span&gt; jar &lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;var&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;lib&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;hadoop&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;hdfs&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;bin&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;hive_mongoDB&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;mongo&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;hadoop&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;core&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;.&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;.&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;.jar;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;add&lt;/span&gt; jar &lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;var&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;lib&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;hadoop&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;hdfs&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;bin&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;hive_mongoDB&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;mongo&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;hadoop&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;hive&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;.&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;.&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;.jar;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;add&lt;/span&gt; jar &lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;var&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;lib&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;hadoop&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;hdfs&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;bin&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;hive_mongoDB&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;mongo&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;java&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;driver&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;.&lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt;.&lt;span style=&#34;color:#ae81ff&#34;&gt;8&lt;/span&gt;.jar;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;set&lt;/span&gt; mongo.&lt;span style=&#34;color:#66d9ef&#34;&gt;input&lt;/span&gt;.split.create_input_splits&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;DROP&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;TABLE&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;IF&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;EXISTS&lt;/span&gt; ods.ods_ex_trade_mdb_wmb_rocket_waimao_company_info_mapping;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;drop&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;table&lt;/span&gt; ods.ods_zxk_annualBusiness_mapping;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;create&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;external&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;table&lt;/span&gt; ods.ods_zxk_annualBusiness_mapping(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;`&lt;/span&gt;_id&lt;span style=&#34;color:#f92672&#34;&gt;`&lt;/span&gt; string,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;companyName string,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Tel string
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)STORED &lt;span style=&#34;color:#66d9ef&#34;&gt;BY&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;com.mongodb.hadoop.hive.MongoStorageHandler&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;WITH&lt;/span&gt; SERDEPROPERTIES(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;mongo.columns.mapping&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{&amp;#34;_id&amp;#34;:&amp;#34;_id&amp;#34;,&amp;#34;companyName&amp;#34;:&amp;#34;companyName&amp;#34;,&amp;#34;Tel&amp;#34;:&amp;#34;Tel&amp;#34;}&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;TBLPROPERTIES(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;mongo.uri&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;mongodb://username:password@172.16.98.159:21000/annualReport.annualBusiness?authSource=admin&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>Hive 字段中文注释乱码</title>
      <link>https://leochu.work/blog/tech/bigdata/hive%E5%AD%97%E6%AE%B5%E4%B8%AD%E6%96%87%E6%B3%A8%E9%87%8A%E4%B9%B1%E7%A0%81%E4%BF%AE%E5%A4%8D/</link>
      <pubDate>Sun, 07 Aug 2022 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/hive%E5%AD%97%E6%AE%B5%E4%B8%AD%E6%96%87%E6%B3%A8%E9%87%8A%E4%B9%B1%E7%A0%81%E4%BF%AE%E5%A4%8D/</guid>
      <description>&lt;p&gt;Hive 字段中文乱码，如执行 show create table xxx 时，表级别注释、字段级别注释发现有乱码现象（都是？？？？）， 一般都是由 hive 元数据库的配置不当造成的。 &lt;/p&gt;
&lt;p&gt;此时可按如下步骤进行配置调整：&lt;/p&gt;
&lt;p&gt;登录 hive 的元数据库 mysql 中：&lt;/p&gt;
&lt;p&gt;&lt;em&gt;1、设置 hive 元数据库字符集&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;show create database hive;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;查看为 utf8，需变更为 latin1&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;_alter database hive character set latin1; &lt;/p&gt;
&lt;p&gt;&lt;em&gt;2、更改如下表字段为字符集编码为 utf8&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;①修改表字段注解和表注解&lt;br&gt;
alter table COLUMNS_V2 modify column COMMENT varchar(256) character set utf8&lt;br&gt;
alter table TABLE_PARAMS modify column PARAM_VALUE varchar(4000) character set utf8&lt;br&gt;
② 修改分区字段注解：&lt;br&gt;
alter table PARTITION_PARAMS modify column PARAM_VALUE varchar(4000) character set utf8 ;&lt;br&gt;
alter table PARTITION_KEYS modify column PKEY_COMMENT varchar(4000) character set utf8;&lt;br&gt;
③修改索引注解：&lt;br&gt;
alter table INDEX_PARAMS modify column PARAM_VALUE varchar(4000) character set utf8;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Hive 数仓建表该选用 ORC 还是 Parquet，压缩选 LZO 还是 Snappy</title>
      <link>https://leochu.work/blog/tech/bigdata/hive%E5%BB%BA%E8%A1%A8%E6%A0%BC%E5%BC%8F%E9%80%89%E5%9E%8B-orc-parquet-lzo-snappy/</link>
      <pubDate>Sun, 24 Jul 2022 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/hive%E5%BB%BA%E8%A1%A8%E6%A0%BC%E5%BC%8F%E9%80%89%E5%9E%8B-orc-parquet-lzo-snappy/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;在数仓中，建议大家除了接口表（从其他数据库导入或者是最后要导出到其他数据库的表），其余表的存储格式与压缩格式保持一致。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在数仓中，建议大家除了接口表（从其他数据库导入或者是最后要导出到其他数据库的表），其余表的存储格式与压缩格式保持一致。&lt;/p&gt;
&lt;p&gt;我们先来说一下目前 Hive 表主流的存储格式与压缩方式&lt;/p&gt;
&lt;p&gt;从 Hive 官网得知，Apache Hive 支持 Apache Hadoop 中使用的几种熟悉的文件格式，如 &lt;code&gt;TextFile（文本格式）&lt;/code&gt;，&lt;code&gt;RCFile（行列式文件）&lt;/code&gt;，&lt;code&gt;SequenceFile（二进制序列化文件）&lt;/code&gt;，&lt;code&gt;AVRO&lt;/code&gt;，&lt;code&gt;ORC（优化的行列式文件）&lt;/code&gt;和&lt;code&gt;Parquet&lt;/code&gt; 格式，而这其中我们目前使用最多的是&lt;code&gt;TextFile&lt;/code&gt;，&lt;code&gt;SequenceFile&lt;/code&gt;，&lt;code&gt;ORC&lt;/code&gt;和&lt;code&gt;Parquet&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;下面来详细了解下这 2 种行列式存储。&lt;/p&gt;
&lt;h2 id=&#34;1orc&#34;&gt;1、ORC&lt;/h2&gt;
&lt;h3 id=&#34;11-orc-的存储结构&#34;&gt;1.1 ORC 的存储结构&lt;/h3&gt;
&lt;p&gt;我们先从官网上拿到 ORC 的存储模型图&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://www.doitedu.cn/wp-content/uploads/2021/12/a.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;看起来略微有点复杂，那我们稍微简化一下，我画了一个简单的图来说明一下&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://www.doitedu.cn/wp-content/uploads/2021/12/b-1024x456.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;但是由于索引的高成本，在**「目前的 Hive3.X 中，已经废除了索引」**，当然也早就引入了列式存储。&lt;/p&gt;
&lt;p&gt;列式存储的存储方式，是按照一列一列存储的，如上图中的右图，这样的话如果查询一个字段的数据，就等于是索引查询，效率高。但是如果需要查全表，它因为需要分别取所有的列最后汇总，反而更占用资源。于是 ORC 行列式存储出现了。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在需要全表扫描时，可以按照行组读取&lt;/li&gt;
&lt;li&gt;如果需要取列数据，在行组的基础上，读取指定的列，而不需要所有行组内所有行的数据和一行内所有字段的数据。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;了解了 ORC 存储的基本逻辑后，我们再来看看它的存储模型图。&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;http://www.doitedu.cn/wp-content/uploads/2021/12/c.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;同时我也把详细的文字也附在下面，大家可以对照着看看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;条带 (stripe)：ORC 文件存储数据的地方，每个 stripe 一般为 HDFS 的块大小。（包含以下 3 部分）&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;index data:保存了所在条带的一些统计信息,以及数据在 stripe中的位置索引信息。
rows data:数据存储的地方,由多个行组构成，每10000行构成一个行组，数据以流( stream)的形式进行存储。
stripe footer:保存数据所在的文件目录
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;文件脚注 (file footer)：包含了文件中 sipe 的列表, 每个 stripe 的行数, 以及每个列的数据类型。它还包含每个列的最小值、最大值、行计数、求和等聚合信息。&lt;/li&gt;
&lt;li&gt;postscript：含有压缩参数和压缩大小相关的信息&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以其实发现，ORC 提供了 3 级索引，文件级、条带级、行组级，所以在查询的时候，利用这些索引可以规避大部分不满足查询条件的文件和数据块。&lt;/p&gt;</description>
    </item>
    <item>
      <title>hadoop默认端口</title>
      <link>https://leochu.work/blog/tech/bigdata/hadoop%E9%BB%98%E8%AE%A4%E7%AB%AF%E5%8F%A3/</link>
      <pubDate>Sun, 10 Jul 2022 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/hadoop%E9%BB%98%E8%AE%A4%E7%AB%AF%E5%8F%A3/</guid>
      <description>&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&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;9000&lt;/td&gt;
          &lt;td&gt;fs.defaultFS，如：hdfs://172.25.40.171:9000&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;9001&lt;/td&gt;
          &lt;td&gt;dfs.namenode.rpc-address，DataNode会连接这个端口&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;50070&lt;/td&gt;
          &lt;td&gt;dfs.namenode.http-address&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;50470&lt;/td&gt;
          &lt;td&gt;dfs.namenode.https-address&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;50100&lt;/td&gt;
          &lt;td&gt;dfs.namenode.backup.address&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;50105&lt;/td&gt;
          &lt;td&gt;dfs.namenode.backup.http-address&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;50090&lt;/td&gt;
          &lt;td&gt;dfs.namenode.secondary.http-address，如：172.25.39.166:50090&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;50091&lt;/td&gt;
          &lt;td&gt;dfs.namenode.secondary.https-address，如：172.25.39.166:50091&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;50020&lt;/td&gt;
          &lt;td&gt;dfs.datanode.ipc.address&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;50075&lt;/td&gt;
          &lt;td&gt;dfs.datanode.http.address&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;50475&lt;/td&gt;
          &lt;td&gt;dfs.datanode.https.address&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;50010&lt;/td&gt;
          &lt;td&gt;dfs.datanode.address，DataNode的数据传输端口&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;8480&lt;/td&gt;
          &lt;td&gt;dfs.journalnode.rpc-address&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;8481&lt;/td&gt;
          &lt;td&gt;dfs.journalnode.https-address&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;8032&lt;/td&gt;
          &lt;td&gt;yarn.resourcemanager.address&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;8088&lt;/td&gt;
          &lt;td&gt;yarn.resourcemanager.webapp.address，YARN的http端口&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;8090&lt;/td&gt;
          &lt;td&gt;yarn.resourcemanager.webapp.https.address&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;8030&lt;/td&gt;
          &lt;td&gt;yarn.resourcemanager.scheduler.address&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;8031&lt;/td&gt;
          &lt;td&gt;yarn.resourcemanager.resource-tracker.address&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;8033&lt;/td&gt;
          &lt;td&gt;yarn.resourcemanager.admin.address&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;8042&lt;/td&gt;
          &lt;td&gt;yarn.nodemanager.webapp.address&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;8040&lt;/td&gt;
          &lt;td&gt;yarn.nodemanager.localizer.address&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;8188&lt;/td&gt;
          &lt;td&gt;yarn.timeline-service.webapp.address&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;10020&lt;/td&gt;
          &lt;td&gt;mapreduce.jobhistory.address&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;19888&lt;/td&gt;
          &lt;td&gt;mapreduce.jobhistory.webapp.address&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;2888&lt;/td&gt;
          &lt;td&gt;ZooKeeper，如果是Leader，用来监听Follower的连接&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;3888&lt;/td&gt;
          &lt;td&gt;ZooKeeper，用于Leader选举&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;2181&lt;/td&gt;
          &lt;td&gt;ZooKeeper，用来监听客户端的连接&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;60010&lt;/td&gt;
          &lt;td&gt;hbase.master.info.port，HMaster的http端口&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;60000&lt;/td&gt;
          &lt;td&gt;hbase.master.port，HMaster的RPC端口&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;60030&lt;/td&gt;
          &lt;td&gt;hbase.regionserver.info.port，HRegionServer的http端口&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;60020&lt;/td&gt;
          &lt;td&gt;hbase.regionserver.port，HRegionServer的RPC端口&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;8080&lt;/td&gt;
          &lt;td&gt;hbase.rest.port，HBase REST server的端口&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;10000&lt;/td&gt;
          &lt;td&gt;hive.server2.thrift.port&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;9083&lt;/td&gt;
          &lt;td&gt;hive.metastore.uris&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;</description>
    </item>
    <item>
      <title>flume示例</title>
      <link>https://leochu.work/blog/tech/bigdata/flume%E7%A4%BA%E4%BE%8B/</link>
      <pubDate>Sun, 26 Jun 2022 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/flume%E7%A4%BA%E4%BE%8B/</guid>
      <description>&lt;p&gt;conf：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# ex_trade.conf:外贸数据自kafka接入hdfs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 配置负责人：褚天宇&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 配置时间： 2022-01-17&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 配置Agent ex_trade_agent各个组件的名称&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ex_trade_agent&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sources &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; r1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ex_trade_agent&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sinks &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; k1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ex_trade_agent&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;channels &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; c1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 配置Agent ex_trade_agent的source r1的属性&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 设置kafka源&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ex_trade_agent&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sources&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;r1&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;type &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; org&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;apache&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;flume&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;source&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;kafka&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;KafkaSource
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 设置kafka消费者组id （不能改动！改动会丢失已记录的offset）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ex_trade_agent&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sources&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;r1&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;kafka&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;consumer&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;group&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;id &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; ex_trade_flume
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ex_trade_agent&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sources&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;r1&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;kafka&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;bootstrap&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;servers &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;192.168.102.2&lt;/span&gt;:&lt;span style=&#34;color:#ae81ff&#34;&gt;9092&lt;/span&gt;,&lt;span style=&#34;color:#ae81ff&#34;&gt;192.168.102.3&lt;/span&gt;:&lt;span style=&#34;color:#ae81ff&#34;&gt;9092&lt;/span&gt;,&lt;span style=&#34;color:#ae81ff&#34;&gt;192.168.102.7&lt;/span&gt;:&lt;span style=&#34;color:#ae81ff&#34;&gt;9092&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ex_trade_agent&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sources&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;r1&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;kafka&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;topics &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; ex_trade
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 一批写入 channel 的最大消息数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ex_trade_agent&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sources&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;r1&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;batchSize &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 一个批次写入 channel 之前的最大等待时间（毫秒）。达到等待时间或者数量达到 batchSize 都会触发写操作&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ex_trade_agent&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sources&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;r1&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;batchDurationMillis &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 设置kafka-offset策略为从头消费&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ex_trade_agent&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sources&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;r1&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;kafka&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;consumer&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;auto&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;offset&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;reset &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; earliest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 配置Agent ex_trade_agent的sink k1的属性&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 配置hdfs目标&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ex_trade_agent&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sinks&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;k1&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;type &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; hdfs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 配置hdfs写入目录，每天一个文件夹，为之后hive表按日分区做准备&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ex_trade_agent&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sinks&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;k1&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;hdfs&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;path &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;flume&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;ex_trade&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;date&lt;span style=&#34;color:#f92672&#34;&gt;=%&lt;/span&gt;Y&lt;span style=&#34;color:#f92672&#34;&gt;%&lt;/span&gt;m&lt;span style=&#34;color:#f92672&#34;&gt;%&lt;/span&gt;d&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 配置文件前缀&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ex_trade_agent&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sinks&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;k1&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;hdfs&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;filePrefix &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; ex_trade_
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 配置数据类型为原样输出&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ex_trade_agent&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sinks&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;k1&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;hdfs&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;fileType &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; DataStream
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 当前文件写入达到该值时间后触发滚动创建新文件，单位：秒，设置为1天防止产生小文件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ex_trade_agent&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sinks&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;k1&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;hdfs&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;rollInterval &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;86400&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 当前文件写入达到该大小后触发滚动创建新文件，单位：字节，设置为128M&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ex_trade_agent&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sinks&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;k1&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;hdfs&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;rollSize &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;134217700&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 向 HDFS 写入内容时每次批量操作的 Event 数量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ex_trade_agent&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sinks&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;k1&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;hdfs&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;batchSize &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 不根据 Event 数量来分割文件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ex_trade_agent&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sinks&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;k1&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;hdfs&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;rollCount &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 文件写入格式设置为 Text，否则 Impala或 Apache Hive 无法读取这些文件。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ex_trade_agent&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sinks&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;k1&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;hdfs&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;writeFormat &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Text
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 配置Agent ex_trade_agent的channel c1的属性，用来缓冲数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ex_trade_agent&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;channels&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;c1&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;type &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; file
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 配置通道的检查点目录&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ex_trade_agent&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;channels&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;c1&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;checkpointDir &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;data&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;deploy&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;flume&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;checkpoint
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 配置通道的数据目录&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ex_trade_agent&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;channels&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;c1&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;dataDirs &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;data&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;deploy&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;flume&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;data
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 把source和sink绑定到channel上&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ex_trade_agent&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sources&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;r1&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;channels &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; c1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ex_trade_agent&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;sinks&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;k1&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;channel &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; c1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;启动脚本：&lt;/p&gt;</description>
    </item>
    <item>
      <title>flume动态加载配置原理</title>
      <link>https://leochu.work/blog/tech/bigdata/flume%E5%8A%A8%E6%80%81%E5%8A%A0%E8%BD%BD%E9%85%8D%E7%BD%AE%E5%8E%9F%E7%90%86/</link>
      <pubDate>Sun, 12 Jun 2022 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/flume%E5%8A%A8%E6%80%81%E5%8A%A0%E8%BD%BD%E9%85%8D%E7%BD%AE%E5%8E%9F%E7%90%86/</guid>
      <description>&lt;h2 id=&#34;flume-ng支持运行时动态修改配置的配置模块&#34;&gt;Flume NG支持运行时动态修改配置的配置模块&lt;/h2&gt;
&lt;p&gt;细说一下PollingPropertiesFileConfigurationProvider提供的运行时动态修改配置并生效的能力。&lt;/p&gt;
&lt;p&gt;要实现动态修改配置文件并生效，主要有两个待实现的功能&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;观察配置文件是否修改&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果修改，将修改的内容通知给观察者&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;对于第一点，监控配置文件是否修改，Flume NG定义了一个FileWatcherRunnable对象来监控配置文件，启动了一个单独的线程采用定时轮询的方式来监控，轮询频率是30毫秒一次，比较file.lastModified属性与lastChange时间戳，当file.lastModified &amp;gt; lastChange时表示文件被修改&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;FileWatcherRunnable&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;implements&lt;/span&gt; Runnable {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;final&lt;/span&gt; File file;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;final&lt;/span&gt; CounterGroup counterGroup;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;private&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;long&lt;/span&gt; lastChange;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;FileWatcherRunnable&lt;/span&gt;(File file, CounterGroup counterGroup) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;super&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;this&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;file&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; file;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;this&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;counterGroup&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; counterGroup;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;this&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;lastChange&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0L;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;@Override&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;run&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      LOGGER.&lt;span style=&#34;color:#a6e22e&#34;&gt;debug&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Checking file:{} for changes&amp;#34;&lt;/span&gt;, file);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      counterGroup.&lt;span style=&#34;color:#a6e22e&#34;&gt;incrementAndGet&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;file.checks&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;long&lt;/span&gt; lastModified &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; file.&lt;span style=&#34;color:#a6e22e&#34;&gt;lastModified&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (lastModified &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; lastChange) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        LOGGER.&lt;span style=&#34;color:#a6e22e&#34;&gt;info&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Reloading configuration file:{}&amp;#34;&lt;/span&gt;, file);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        counterGroup.&lt;span style=&#34;color:#a6e22e&#34;&gt;incrementAndGet&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;file.loads&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        lastChange &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; lastModified;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;try&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          eventBus.&lt;span style=&#34;color:#a6e22e&#34;&gt;post&lt;/span&gt;(getConfiguration());
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        } &lt;span style=&#34;color:#66d9ef&#34;&gt;catch&lt;/span&gt; (Exception e) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          LOGGER.&lt;span style=&#34;color:#a6e22e&#34;&gt;error&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Failed to load configuration data. Exception follows.&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              e);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        } &lt;span style=&#34;color:#66d9ef&#34;&gt;catch&lt;/span&gt; (NoClassDefFoundError e) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          LOGGER.&lt;span style=&#34;color:#a6e22e&#34;&gt;error&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Failed to start agent because dependencies were not &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;found in classpath. Error follows.&amp;#34;&lt;/span&gt;, e);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        } &lt;span style=&#34;color:#66d9ef&#34;&gt;catch&lt;/span&gt; (Throwable t) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#75715e&#34;&gt;// caught because the caller does not handle or log Throwables&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          LOGGER.&lt;span style=&#34;color:#a6e22e&#34;&gt;error&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Unhandled error&amp;#34;&lt;/span&gt;, t);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// PollingPropertiesFileConfigurationProvider.start()启动一个单独的线程来监控properties配置文件&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;start&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    LOGGER.&lt;span style=&#34;color:#a6e22e&#34;&gt;info&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Configuration provider starting&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Preconditions.&lt;span style=&#34;color:#a6e22e&#34;&gt;checkState&lt;/span&gt;(file &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;null&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;The parameter file must not be null&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    executorService &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Executors.&lt;span style=&#34;color:#a6e22e&#34;&gt;newSingleThreadScheduledExecutor&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; ThreadFactoryBuilder().&lt;span style=&#34;color:#a6e22e&#34;&gt;setNameFormat&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;conf-file-poller-%d&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                .&lt;span style=&#34;color:#a6e22e&#34;&gt;build&lt;/span&gt;());
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    FileWatcherRunnable fileWatcherRunnable &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;new&lt;/span&gt; FileWatcherRunnable(file, counterGroup);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    executorService.&lt;span style=&#34;color:#a6e22e&#34;&gt;scheduleWithFixedDelay&lt;/span&gt;(fileWatcherRunnable, 0, interval,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        TimeUnit.&lt;span style=&#34;color:#a6e22e&#34;&gt;SECONDS&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    lifecycleState &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; LifecycleState.&lt;span style=&#34;color:#a6e22e&#34;&gt;START&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    LOGGER.&lt;span style=&#34;color:#a6e22e&#34;&gt;debug&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Configuration provider started&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;对于第二点，利用Guava EventBus提供的发布订阅模式机制，将配置修改封装成事件传递给Application，来重新加载配置&lt;/p&gt;</description>
    </item>
    <item>
      <title>CDH组件参数调优</title>
      <link>https://leochu.work/blog/tech/bigdata/cdh%E7%BB%84%E4%BB%B6%E5%8F%82%E6%95%B0%E8%B0%83%E4%BC%98/</link>
      <pubDate>Sun, 29 May 2022 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/cdh%E7%BB%84%E4%BB%B6%E5%8F%82%E6%95%B0%E8%B0%83%E4%BC%98/</guid>
      <description>&lt;h3 id=&#34;1yarn参数调优&#34;&gt;1.YARN参数调优&lt;/h3&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;&lt;strong&gt;检查项&lt;/strong&gt;&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;当前值&lt;/strong&gt;&lt;/th&gt;
          &lt;th&gt;&lt;strong&gt;修改值&lt;/strong&gt;&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;JobHistory Server 的 Java 堆栈大小&lt;/td&gt;
          &lt;td&gt;1GB&lt;/td&gt;
          &lt;td&gt;2GB&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;NodeManager 的 Java 堆栈大小&lt;/td&gt;
          &lt;td&gt;1GB&lt;/td&gt;
          &lt;td&gt;2GB&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;ResourceManager 的 Java 堆栈大小&lt;/td&gt;
          &lt;td&gt;1GB&lt;/td&gt;
          &lt;td&gt;2GB&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;容器内存  yarn.nodemanager.resource.memory-mb&lt;/td&gt;
          &lt;td&gt;24GB&lt;/td&gt;
          &lt;td&gt;32GB&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;最小容器内存   yarn.scheduler.minimum-allocation-mb&lt;/td&gt;
          &lt;td&gt;10GB&lt;/td&gt;
          &lt;td&gt;8GB&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;最大容器内存  yarn.scheduler.maximum-allocation-mb&lt;/td&gt;
          &lt;td&gt;40GB&lt;/td&gt;
          &lt;td&gt;56GB&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Map 任务内存   mapreduce.map.memory.mb&lt;/td&gt;
          &lt;td&gt;0M&lt;/td&gt;
          &lt;td&gt;12GB&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Reduce 任务内存   mapreduce.reduce.memory.mb&lt;/td&gt;
          &lt;td&gt;0M&lt;/td&gt;
          &lt;td&gt;24GB&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Application Master容器内存  yarn.app.mapreduce.am.resource.mb&lt;/td&gt;
          &lt;td&gt;24GB&lt;/td&gt;
          &lt;td&gt;32GB&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Map 任务 Java 选项库  mapreduce.map.java.opts&lt;/td&gt;
          &lt;td&gt;-Djava.net.preferIPv4Stack=true&lt;/td&gt;
          &lt;td&gt;-Dmapreduce.map.java.opts=-Xmx2048m&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Reduce 任务 Java 选项库  mapreduce.reduce.java.opts&lt;/td&gt;
          &lt;td&gt;-Djava.net.preferIPv4Stack=true&lt;/td&gt;
          &lt;td&gt;-Dmapreduce.reduce.java.opts=-Xmx2048m&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;yarn.resourcemanager.scheduler.class&lt;/td&gt;
          &lt;td&gt;org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler&lt;/td&gt;
          &lt;td&gt;org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;yarn.scheduler.capacity.root.queues:&lt;/p&gt;
&lt;p&gt;当前值：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;name&amp;gt;&lt;/span&gt;yarn.scheduler.capacity.root.queues&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;value&amp;gt;&lt;/span&gt;default&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;name&amp;gt;&lt;/span&gt;yarn.scheduler.capacity.root.capacity&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;value&amp;gt;&lt;/span&gt;100&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;name&amp;gt;&lt;/span&gt;yarn.scheduler.capacity.root.default.capacity&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;value&amp;gt;&lt;/span&gt;100&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;修改值：&lt;/p&gt;</description>
    </item>
    <item>
      <title>CDH角色划分</title>
      <link>https://leochu.work/blog/tech/bigdata/cdh%E8%A7%92%E8%89%B2%E5%88%92%E5%88%86/</link>
      <pubDate>Sun, 15 May 2022 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/cdh%E8%A7%92%E8%89%B2%E5%88%92%E5%88%86/</guid>
      <description>&lt;h3 id=&#34;1-服务器配置&#34;&gt;&lt;strong&gt;1. 服务器配置&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id=&#34;主节点&#34;&gt;&lt;strong&gt;主节点：&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;hostname: m1,m2,m3&lt;/p&gt;
&lt;p&gt;vcore：48&lt;/p&gt;
&lt;p&gt;内存：128G&lt;/p&gt;
&lt;p&gt;SSD：1T（不算系统盘）&lt;/p&gt;
&lt;h4 id=&#34;工作节点&#34;&gt;&lt;strong&gt;工作节点：&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;hostname: n1,n2,n3,n4&lt;/p&gt;
&lt;p&gt;vcore : 48&lt;/p&gt;
&lt;p&gt;内存：256G&lt;/p&gt;
&lt;p&gt;SSD:1T（不算系统盘）&lt;/p&gt;
&lt;h3 id=&#34;2-节点职责描述&#34;&gt;&lt;strong&gt;2. 节点职责描述&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;m1: 控制核心；cdh核心，hadoop主节点&lt;/p&gt;
&lt;p&gt;m2: 网关入口；主节点高可用，一些组件的web ui，用户入口 ，（前期做计算任务的driver端，后期优化driver打散到各节点）&lt;/p&gt;
&lt;p&gt;m3: 后台服务；组件元数据库，任务的history服务 ，（后期做元数据HA）&lt;/p&gt;
&lt;p&gt;n1~n4: 算存一体；提供存储，计算等服务&lt;/p&gt;
&lt;h3 id=&#34;3角色分配策略&#34;&gt;&lt;strong&gt;3.角色分配策略&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id=&#34;一hdfs&#34;&gt;&lt;strong&gt;一、hdfs&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;NameNode一般在主节点上，初始化安装的时候没有高可用，所以有SecondaryNameNode的作为一个备份,NameNode它会将它拆分后进行分布式存储，其中的数据是分散在各个DataNode节点，且默认都会有3个副本，防止其中一台机器宕机使得数据缺失。balancer一般与namenode搭建在一起。&lt;/p&gt;
&lt;h4 id=&#34;二hive&#34;&gt;&lt;strong&gt;二、hive&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;hive metastore server与hiveServer2一般搭载一起上，但也可以分开，因为hive服务需要启动hiveServer2，访问sparksql需要启动metastore而hive gateway,事实上并不是真正的角色，也没有状态，但它们充当了告诉客户端配置应该放置在哪里。 添加Hive服务时，默认情况下会创建Hive网关。&lt;/p&gt;
&lt;h4 id=&#34;三cloudera-manager-server&#34;&gt;&lt;strong&gt;三、cloudera manager server&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;这个可以根据实际搭建，这个相当于是集群的监听器，在网页上出现的的图表也就是这个监听器类似的，这个可以搭建在主节点上，但若是主节点上分配的角色过多会影响其服务器的性能。&lt;/p&gt;
&lt;h4 id=&#34;四spark&#34;&gt;&lt;strong&gt;四、spark&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;这个角色可以分配这任意的机器上，按实际情况调整。spark-gateway全部部署在各个机器上，这个对于个人理解来说相当于spark、spark2机器之间的通信功能。&lt;/p&gt;
&lt;h4 id=&#34;五yarn&#34;&gt;&lt;strong&gt;五、yarn&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;jobhistory与resourcemanager进行通信，所以部署上一般在同一台机器上放在主节点上，而nodemanager分配在各个节点上&lt;/p&gt;
&lt;h4 id=&#34;六zookeeper&#34;&gt;&lt;strong&gt;六、zookeeper&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;这个若是机器足够一般是奇数的，所以部署在m节点上比较合适。&lt;strong&gt;奇数台、高可用、与管理角色共置&lt;/strong&gt;&lt;/p&gt;
&lt;h4 id=&#34;七hue&#34;&gt;&lt;strong&gt;七、hue&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;会对外提供一个web ui，以便于数据分析和数据开发做即席查询。这个服务随意部署，根据自己的机器部署情况来看。&lt;/p&gt;
&lt;h3 id=&#34;4角色划分详情表&#34;&gt;&lt;strong&gt;4.角色划分详情表&lt;/strong&gt;&lt;/h3&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;th&gt;&lt;/th&gt;
          &lt;th&gt;&lt;/th&gt;
          &lt;th&gt;&lt;/th&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;&lt;/td&gt;
          &lt;td&gt;控制核心&lt;/td&gt;
          &lt;td&gt;网关+入口&lt;/td&gt;
          &lt;td&gt;元数据+历史服务&lt;/td&gt;
          &lt;td&gt;存算一体&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;m1&lt;/td&gt;
          &lt;td&gt;m2&lt;/td&gt;
          &lt;td&gt;m3&lt;/td&gt;
          &lt;td&gt;n1&lt;/td&gt;
          &lt;td&gt;n2&lt;/td&gt;
          &lt;td&gt;n3&lt;/td&gt;
          &lt;td&gt;n4&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;cloudera management&lt;/td&gt;
          &lt;td&gt;Alert Publisher&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Event Server&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Host Monitor&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Service Monitor&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;hdfs&lt;/td&gt;
          &lt;td&gt;NameNode&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;JournalNode&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Failover Controller&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;HttpFs&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;DataNode&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;yarn&lt;/td&gt;
          &lt;td&gt;ResourceManager&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;NodeManager&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;JobHistory Server&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;hive&lt;/td&gt;
          &lt;td&gt;Hive MetaStore Server&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;HiveServer2&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;HiveGateway&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;spark&lt;/td&gt;
          &lt;td&gt;Spark History Server&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Spark Gateway&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;impala&lt;/td&gt;
          &lt;td&gt;Impala StateStore&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Impala catalog Server&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Impala Daemon&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;zookeeper&lt;/td&gt;
          &lt;td&gt;zk-node&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;hue&lt;/td&gt;
          &lt;td&gt;Hue Server&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Hue Load Balancer&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;✅&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;5-未来升级项&#34;&gt;5. 未来升级项&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;work节点扩展硬盘，只需将新盘挂载到新目录/hadoop/data2或/hadoop/data3，更新hdfs配置就能完成存储扩展（支持热加入）&lt;/p&gt;</description>
    </item>
    <item>
      <title>beeline导出数据</title>
      <link>https://leochu.work/blog/tech/bigdata/beeline%E5%AF%BC%E5%87%BA%E6%95%B0%E6%8D%AE/</link>
      <pubDate>Sun, 01 May 2022 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/beeline%E5%AF%BC%E5%87%BA%E6%95%B0%E6%8D%AE/</guid>
      <description>&lt;p&gt;beeline  -n  chutianyu -p chutianyu &amp;ndash;showHeader=false  &amp;ndash;outputformat=csv2  -e  &amp;ldquo;select * from smp.india_imp_json_test2mongo ;&amp;rdquo; &amp;gt;  india_imp_test1.json&lt;/p&gt;</description>
    </item>
    <item>
      <title>如何重设消费者组位移</title>
      <link>https://leochu.work/blog/tech/bigdata/%E5%A6%82%E4%BD%95%E9%87%8D%E8%AE%BE%E6%B6%88%E8%B4%B9%E8%80%85%E7%BB%84%E4%BD%8D%E7%A7%BB/</link>
      <pubDate>Sun, 17 Apr 2022 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/%E5%A6%82%E4%BD%95%E9%87%8D%E8%AE%BE%E6%B6%88%E8%B4%B9%E8%80%85%E7%BB%84%E4%BD%8D%E7%A7%BB/</guid>
      <description>&lt;h2 id=&#34;为什么要重设消费者组位移&#34;&gt;为什么要重设消费者组位移？&lt;/h2&gt;
&lt;hr&gt;
&lt;p&gt;我们知道，Kafka 和传统的消息引擎在设计上是有很大区别的，其中一个比较显著的区别就是，Kafka 的消费者读取消息是可以重演的（replayable）。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;像 RabbitMQ 或 ActiveMQ 这样的传统消息中间件，它们处理和响应消息的方式是破坏性的（destructive），即一旦消息被成功处理，就会被从 Broker 上删除。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;反观 Kafka，由于它是基于日志结构（log-based）的消息引擎，消费者在消费消息时，仅仅是从磁盘文件上读取数据而已，是只读的操作，因此消费者不会删除消息数据。同时，由于位移数据是由消费者控制的，因此它能够很容易地修改位移的值，实现重复消费历史数据的功能。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;对了，之前有很多同学在专栏的留言区提问：&lt;em&gt;在实际使用场景中，我该如何确定是使用传统的消息中间件，还是使用 Kafka 呢？我在这里统一回答一下。如果在你的场景中，消息处理逻辑非常复杂，处理代价很高，同时你又不关心消息之间的顺序，那么传统的消息中间件是比较合适的；反之，如果你的场景需要较高的吞吐量，但每条消息的处理时间很短，同时你又很在意消息的顺序，此时，Kafka 就是你的首选。&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;重设位移策略&#34;&gt;重设位移策略&lt;/h2&gt;
&lt;hr&gt;
&lt;p&gt;不论是哪种设置方式，重设位移大致可以从两个维度来进行。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;位移维度。这是指根据位移值来重设。也就是说，直接把消费者的位移值重设成我们给定的位移值。&lt;/li&gt;
&lt;li&gt;时间维度。我们可以给定一个时间，让消费者把位移调整成大于该时间的最小位移；也可以给出一段时间间隔，比如 30 分钟前，然后让消费者直接将位移调回 30 分钟之前的位移值。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;下面的这张表格罗列了 7 种重设策略。接下来，我来详细解释下这些策略。&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20230328140507.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230328140507.png&#34;&gt;
Earliest 策略表示将位移调整到主题当前最早位移处。这个最早位移不一定就是 0，因为在生产环境中，很久远的消息会被 Kafka 自动删除，所以当前最早位移很可能是一个大于 0 的值。&lt;strong&gt;如果你想要重新消费主题的所有消息，那么可以使用 Earliest 策略&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;Latest 策略表示把位移重设成最新末端位移。如果你总共向某个主题发送了 15 条消息，那么最新末端位移就是 15。&lt;strong&gt;如果你想跳过所有历史消息，打算从最新的消息处开始消费的话，可以使用 Latest 策略&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Current 策略表示将位移调整成消费者当前提交的最新位移&lt;/em&gt;。有时候你可能会碰到这样的场景：你修改了消费者程序代码，并重启了消费者，结果发现代码有问题，你需要回滚之前的代码变更，同时也要把位移重设到消费者重启时的位置，那么，Current 策略就可以帮你实现这个功能。&lt;/p&gt;
&lt;p&gt;表中第 4 行的 Specified-Offset 策略则是比较通用的策略，表示消费者把位移值调整到你指定的位移处。&lt;strong&gt;这个策略的典型使用场景是，消费者程序在处理某条错误消息时，你可以手动地 “跳过” 此消息的处理&lt;/strong&gt;。在实际使用过程中，可能会出现 corrupted 消息无法被消费的情形，此时消费者程序会抛出异常，无法继续工作。一旦碰到这个问题，你就可以尝试使用 Specified-Offset 策略来规避。&lt;/p&gt;
&lt;p&gt;如果说 Specified-Offset 策略要求你指定位移的&lt;strong&gt;绝对数值&lt;/strong&gt;的话，那么 Shift-By-N 策略指定的就是位移的&lt;strong&gt;相对数值&lt;/strong&gt;，即你给出要跳过的一段消息的距离即可。这里的 “跳” 是双向的，你既可以向前“跳”，也可以向后“跳”。比如，你想把位移重设成当前位移的前 100 条位移处，此时你需要指定 N 为 -100。&lt;/p&gt;</description>
    </item>
    <item>
      <title>如何调优 Kafka</title>
      <link>https://leochu.work/blog/tech/bigdata/kafka%E8%B0%83%E4%BC%98%E6%8C%87%E5%8D%97/</link>
      <pubDate>Sun, 03 Apr 2022 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/kafka%E8%B0%83%E4%BC%98%E6%8C%87%E5%8D%97/</guid>
      <description>&lt;h2 id=&#34;调优目标&#34;&gt;调优目标&lt;/h2&gt;
&lt;hr&gt;
&lt;p&gt;在做调优之前，我们必须明确优化 Kafka 的目标是什么。通常来说，调优是为了满足系统常见的非功能性需求。在众多的非功能性需求中，性能绝对是我们最关心的那一个。不同的系统对性能有不同的诉求，比如对于数据库用户而言，性能意味着请求的响应时间，用户总是希望查询或更新请求能够被更快地处理完并返回。&lt;/p&gt;
&lt;p&gt;对 Kafka 而言，性能一般是指吞吐量和延时。&lt;/p&gt;
&lt;p&gt;吞吐量，也就是 TPS，是指 Broker 端进程或 Client 端应用程序每秒能处理的字节数或消息数，这个值自然是越大越好。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;延时和我们刚才说的响应时间类似，它表示从 Producer 端发送消息到 Broker 端持久化完成之间的时间间隔。这个指标也可以代表端到端的延时（End-to-End，E2E），也就是从 Producer 发送消息到 Consumer 成功消费该消息的总时长&lt;/em&gt;。和 TPS 相反，我们通常希望延时越短越好。&lt;/p&gt;
&lt;p&gt;总之，高吞吐量、低延时是我们调优 Kafka 集群的主要目标，一会儿我们会详细讨论如何达成这些目标。在此之前，我想先谈一谈优化漏斗的问题。&lt;/p&gt;
&lt;h2 id=&#34;优化漏斗&#34;&gt;优化漏斗&lt;/h2&gt;
&lt;hr&gt;
&lt;p&gt;优化漏斗是一个调优过程中的分层漏斗，我们可以在每一层上执行相应的优化调整。总体来说，层级越靠上，其调优的效果越明显，整体优化效果是自上而下衰减的，如下图所示：&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20230328142440.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020230328142440.png&#34;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;第 1 层：应用程序层。它是指优化 Kafka 客户端应用程序代码。比如，使用合理的数据结构、缓存计算开销大的运算结果，抑或是复用构造成本高的对象实例等。这一层的优化效果最为明显，通常也是比较简单的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;第 2 层：框架层。它指的是合理设置 Kafka 集群的各种参数。毕竟，直接修改 Kafka 源码进行调优并不容易，但根据实际场景恰当地配置关键参数的值，还是很容易实现的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;第 3 层：JVM 层。Kafka Broker 进程是普通的 JVM 进程，各种对 JVM 的优化在这里也是适用的。优化这一层的效果虽然比不上前两层，但有时也能带来巨大的改善效果。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;第 4 层：操作系统层。对操作系统层的优化很重要，但效果往往不如想象得那么好。与应用程序层的优化效果相比，它是有很大差距的。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;基础性调优&#34;&gt;基础性调优&lt;/h2&gt;
&lt;hr&gt;
&lt;p&gt;接下来，我就来分别介绍一下优化漏斗的 4 个分层的调优。&lt;/p&gt;
&lt;h2 id=&#34;操作系统调优&#34;&gt;操作系统调优&lt;/h2&gt;
&lt;p&gt;我先来说说操作系统层的调优。在操作系统层面，你最好在挂载（Mount）文件系统时禁掉 atime 更新。atime 的全称是 access time，记录的是文件最后被访问的时间。记录 atime 需要操作系统访问 inode 资源，而禁掉 atime 可以避免 inode 访问时间的写入操作，减少文件系统的写操作数。你可以执行 &lt;code&gt;mount -o noatime&lt;/code&gt; 命令进行设置。&lt;/p&gt;</description>
    </item>
    <item>
      <title>取消HDP hive默认开启ACID配置</title>
      <link>https://leochu.work/blog/tech/bigdata/%E5%8F%96%E6%B6%88hdp-hive%E9%BB%98%E8%AE%A4%E5%BC%80%E5%90%AFacid%E9%85%8D%E7%BD%AE/</link>
      <pubDate>Sun, 20 Mar 2022 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/%E5%8F%96%E6%B6%88hdp-hive%E9%BB%98%E8%AE%A4%E5%BC%80%E5%90%AFacid%E9%85%8D%E7%BD%AE/</guid>
      <description>&lt;h3 id=&#34;问题描述&#34;&gt;问题描述&lt;/h3&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20231220150234.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020231220150234.png&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;原因排查&#34;&gt;原因排查&lt;/h3&gt;
&lt;p&gt;HDP 的 hive 使用的版本较高为3.1.0  ，默认建表都是使用 ACID 的事务表。而 HDP的spark版本较低为2.3 目前还不支持 hive 的 ACID 功能，因此无法读取 ACID 表的数据，准确来说是内表的数据。&lt;/p&gt;
&lt;h3 id=&#34;官方资料&#34;&gt;官方资料&lt;/h3&gt;
&lt;p&gt;spark issues 地址： &lt;a href=&#34;https://issues.apache.org/jira/browse/SPARK-15348&#34;&gt;SPARK-15348 Hive ACID&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;解决方案&#34;&gt;解决方案&lt;/h3&gt;
&lt;p&gt;修改hive以下配置，重启hive&lt;/p&gt;
&lt;p&gt;hive.strict.managed.tables =false&lt;br&gt;
hive.create.as.insert.only =false&lt;br&gt;
metastore.create.as.acid =false&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20231220150309.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020231220150309.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20231220150319.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020231220150319.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;Pasted image 20231220150325.png&#34; loading=&#34;lazy&#34; src=&#34;https://leochu.work/blog/resource/Pasted%20image%2020231220150325.png&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;其他资料&#34;&gt;其他资料&lt;/h3&gt;
&lt;h4 id=&#34;hive-中支持的表类型和-acid-特性&#34;&gt;Hive 中支持的表类型和 ACID 特性&lt;/h4&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;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;ACID&lt;/td&gt;
          &lt;td&gt;文件格式&lt;/td&gt;
          &lt;td&gt;插入&lt;/td&gt;
          &lt;td&gt;更新 / 删除&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;托管表：CRUD 事务&lt;/td&gt;
          &lt;td&gt;是&lt;/td&gt;
          &lt;td&gt;ORC&lt;/td&gt;
          &lt;td&gt;是&lt;/td&gt;
          &lt;td&gt;是&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;托管表：仅插入式事务&lt;/td&gt;
          &lt;td&gt;是&lt;/td&gt;
          &lt;td&gt;任意格式&lt;/td&gt;
          &lt;td&gt;是&lt;/td&gt;
          &lt;td&gt;没有&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;托管表：临时&lt;/td&gt;
          &lt;td&gt;没有&lt;/td&gt;
          &lt;td&gt;任意格式&lt;/td&gt;
          &lt;td&gt;是&lt;/td&gt;
          &lt;td&gt;没有&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;外部表&lt;/td&gt;
          &lt;td&gt;没有&lt;/td&gt;
          &lt;td&gt;任意格式&lt;/td&gt;
          &lt;td&gt;是&lt;/td&gt;
          &lt;td&gt;没有&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;查看表的属性，指令：&lt;code&gt;desc formatted tb_name&lt;/code&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>大数据常用命令</title>
      <link>https://leochu.work/blog/tech/bigdata/%E5%A4%A7%E6%95%B0%E6%8D%AE%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4/</link>
      <pubDate>Sun, 06 Mar 2022 00:00:00 +0000</pubDate>
      <guid>https://leochu.work/blog/tech/bigdata/%E5%A4%A7%E6%95%B0%E6%8D%AE%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4/</guid>
      <description>&lt;h2 id=&#34;linuxvivim&#34;&gt;Linux（vi/vim）&lt;/h2&gt;
&lt;h3 id=&#34;一般模式&#34;&gt;一般模式&lt;/h3&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&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;yy&lt;/td&gt;
          &lt;td&gt;复制光标当前一行&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;y数字y&lt;/td&gt;
          &lt;td&gt;复制一段（从第几行到第几行）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;p&lt;/td&gt;
          &lt;td&gt;箭头移动到目的行粘贴&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;u&lt;/td&gt;
          &lt;td&gt;撤销上一步&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;dd&lt;/td&gt;
          &lt;td&gt;删除光标当前行&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;d数字d&lt;/td&gt;
          &lt;td&gt;删除光标（含）后多少行&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;x&lt;/td&gt;
          &lt;td&gt;删除一个字母，相当于del&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;X&lt;/td&gt;
          &lt;td&gt;删除一个字母，相当于Backspace&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;yw&lt;/td&gt;
          &lt;td&gt;复制一个词&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;dw&lt;/td&gt;
          &lt;td&gt;删除一个词&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;shift+^&lt;/td&gt;
          &lt;td&gt;移动到行头&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;shift+$&lt;/td&gt;
          &lt;td&gt;移动到行尾&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;1+shift+g&lt;/td&gt;
          &lt;td&gt;移动到页头，数字&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;shift+g&lt;/td&gt;
          &lt;td&gt;移动到页尾&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;数字N+shift+g&lt;/td&gt;
          &lt;td&gt;移动到目标行&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;编辑模式&#34;&gt;编辑模式&lt;/h3&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&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;i&lt;/td&gt;
          &lt;td&gt;当前光标前&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;a&lt;/td&gt;
          &lt;td&gt;当前光标后&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;o&lt;/td&gt;
          &lt;td&gt;当前光标行的下一行&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;I&lt;/td&gt;
          &lt;td&gt;光标所在行最前&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;A&lt;/td&gt;
          &lt;td&gt;光标所在行最后&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;O&lt;/td&gt;
          &lt;td&gt;当前光标行的上一行&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;指令模式&#34;&gt;指令模式&lt;/h3&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&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;:w&lt;/td&gt;
          &lt;td&gt;保存&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;:q&lt;/td&gt;
          &lt;td&gt;退出&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;:!&lt;/td&gt;
          &lt;td&gt;强制执行&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;/要查找的词&lt;/td&gt;
          &lt;td&gt;n 查找下一个，N 往上查找&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;? 要查找的词&lt;/td&gt;
          &lt;td&gt;n是查找上一个，shift+n是往下查找&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;:set nu&lt;/td&gt;
          &lt;td&gt;显示行号&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;:set nonu&lt;/td&gt;
          &lt;td&gt;关闭行号&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;压缩和解压&#34;&gt;压缩和解压&lt;/h3&gt;
&lt;h4 id=&#34;gzipgunzip-压缩&#34;&gt;gzip/gunzip 压缩&lt;/h4&gt;
&lt;p&gt;（1）只能压缩文件不能压缩目录&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
