文章列表

贝壳面试:什么是回表?什么是 索引下推 ?

作者:微信小助手

<section data-tool="mdnice编辑器" data-website="https://www.mdnice.com"> <h2 data-tool="mdnice编辑器" style="font-weight: bold;font-size: 22px;margin: 10px auto 5px;border-top: 1px solid rgb(242, 242, 242);background-color: rgb(242, 242, 242);"><span style="margin-top: -1px;padding-top: 14px;padding-bottom: 14px;padding-right: 5px;padding-left: 5px;font-size: 17px;border-top: 4px solid rgb(33, 33, 34);display: inline-block;line-height: 1.5;font-weight: normal;background-color: rgb(30, 30, 30);border-bottom-right-radius: 100px;color: rgb(255, 255, 255);padding-right: 20px;padding-left: 10px;">本文目录</span></h2> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><strong><span style="font-size: 14px;">-&nbsp;</span></strong></strong><strong>尼恩说在前面</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><span style="font-size: 14px;">-&nbsp;</span></strong>1 回表查询(table lookup)是什么?</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><span style="font-size: 14px;">-&nbsp;</span></strong>1.1 MySQL大概的架构</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><span style="font-size: 14px;">-&nbsp;</span></strong>1.2 回表(table lookup) 的简单介绍</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><span style="font-size: 14px;">-&nbsp;</span></strong>1.3 由浅入深,一步一步理解回表查询(table lookup)</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>基本概念:聚集索引(Clustered Index):</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>基本概念:非聚集索引(Non-Clustered Index):</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>使用案例介绍:回表查询</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><strong><span style="font-size: 14px;">-&nbsp;</span></strong></strong><strong>1.4 回表查询带来的 巨大的问题</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong><span style="font-size: 14px;">-&nbsp;</span>1.5 怎样避免回表查询?</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong><span style="font-size: 14px;">-&nbsp;</span>2 索引下推的底层原理是什么?优势是什么?</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong><span style="font-size: 14px;">-&nbsp;</span>2.1 通俗易懂,介绍一下 索引下推的简单案例</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>最左匹配原则 中的第4条:范围匹配规则</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong><span style="font-size: 14px;">-&nbsp;</span>2.2 没有索引下推场景下 的联合索引范围查询 执行流程</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong><span style="font-size: 14px;">-&nbsp;</span>2.3 图解一下:什么是索引下推?</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>索引下推优化的原理</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><strong><span style="font-size: 14px;">-&nbsp;</span></strong></strong><strong>2.4 索引下推 场景下的联合索引范围查询 执行流程</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><span style="font-size: 14px;">-&nbsp;</span></strong>2.5 通过 explain 演示一下 索引下推工作原理</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>案例分析</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><strong><span style="font-size: 14px;">-&nbsp;</span></strong></strong><strong>2.6 索引下推配置</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><span style="font-size: 14px;">-&nbsp;</span></strong>2.7 &nbsp;通过 explain 演示一下:未启用索引下推 的效果</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><span style="font-size: 14px;">-&nbsp;</span></strong>2.8 通过 explain 演示一下:启用索引下推 的效果</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><span style="font-size: 14px;">-&nbsp;</span></strong>2.9 索引下推使用条件和效果</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>索引下推优化效果</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>索引下推应用范围</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>索引下推适用场景</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><strong><span style="font-size: 14px;">-&nbsp;</span></strong></strong><strong>3 来一张Explain执行计划详解图:</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><span style="font-size: 14px;">-&nbsp;</span></strong>4 mysql调优的相关系统参数</strong></p> <h5 data-sourcepos="299:1-299:178" style="letter-spacing: 0.578px;white-space: normal;"><span style="font-size: 14px;letter-spacing: 0.578px;">&nbsp; &nbsp; -</span><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.034em;">其返回值为如下的形式:</span></h5> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;"><span style="font-size: 14px;">-&nbsp;</span></span>4.1&nbsp;表访问优化参数</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;"><span style="font-size: 14px;">-&nbsp;</span></span>4.2&nbsp;表关联优化参数</strong></p> <h5 data-sourcepos="299:1-299:178" style="letter-spacing: 0.578px;white-space: normal;"><strong><span style="font-size: 14px;letter-spacing: 0.578px;"><span style="font-family: &quot;Helvetica Neue&quot;;letter-spacing: 0.578px;font-size: 14px;"><span style="font-size: 14px;">-&nbsp;</span></span><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;">4.</span></span><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.034em;">3&nbsp;子查询优化参数</span></strong></h5> <h5 data-sourcepos="299:1-299:178" style="letter-spacing: 0.578px;white-space: normal;"><strong><span style="font-size: 14px;letter-spacing: 0.578px;"><span style="font-family: &quot;Helvetica Neue&quot;;letter-spacing: 0.578px;font-size: 14px;"><span style="font-size: 14px;">-&nbsp;</span></span><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;">4.</span></span><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.034em;">4&nbsp;其他优化参数</span></strong></h5> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;PingFang SC&quot;;"><span style="font-stretch: normal;font-family: &quot;Helvetica Neue&quot;;"><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><strong><span style="font-size: 14px;">-&nbsp;</span></strong></strong></span><strong>说在最后:有问题找老架构取经<span style="font-stretch: normal;font-family: &quot;Helvetica Neue&quot;;">‍</span></strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;PingFang SC&quot;;"><strong><span style="font-stretch: normal;font-family: &quot;Helvetica Neue&quot;;"><br></span></strong></p> <h2 data-sourcepos="21:1-21:49" style="font-weight: bold;font-size: 22px;margin: 10px auto 5px;border-top-width: 1px;border-top-style: solid;border-top-color: rgb(242, 242, 242);background-color: rgb(242, 242, 242);"><span style="margin-top: -1px;padding-top: 14px;padding-bottom: 14px;padding-right: 5px;padding-left: 5px;font-size: 17px;border-top: 4px solid rgb(33, 33, 34);display: inline-block;line-height: 1.5;font-weight: normal;background-color: rgb(30, 30, 30);border-bottom-right-radius: 100px;color: rgb(255, 255, 255);padding-right: 20px;padding-left: 10px;">1 什么是 回表(table lookup)?</span></h2> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">尼恩的叙事风格:故事从最基础的地方讲起。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">先简单了解一下MySQL大概的架构:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">再由浅入深,一步一步理解回表查询(table lookup)</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">然后介绍,<strong>回表(table lookup)查询带来的 巨大的问题</strong></span> </section> <h2 data-sourcepos="33:1-33:27" style="font-weight: bold;font-size: 22px;margin: 10px auto 5px;border-top-width: 1px;border-top-style: solid;border-top-color: rgb(242, 242, 242);background-color: rgb(242, 242, 242);"><span style="margin-top: -1px;padding-top: 14px;padding-bottom: 14px;padding-right: 5px;padding-left: 5px;font-size: 17px;border-top: 4px solid rgb(33, 33, 34);display: inline-block;line-height: 1.5;font-weight: normal;background-color: rgb(30, 30, 30);border-bottom-right-radius: 100px;color: rgb(255, 255, 255);padding-right: 20px;padding-left: 10px;">1.1 MySQL大概的架构</span></h2> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">尼恩的叙事风格:故事从最基础的地方讲起。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">先简单了解一下MySQL大概的架构:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <img class="rich_pages wxw-img" data-imgfileid="100019772" data-ratio="0.9157407407407407" src="/upload/04a547e2438bacb8346bdb8fd9d0f58a.png" data-type="png" data-w="1080" style="box-sizing: content-box;border-style: none;background-color: rgb(255, 255, 255);"> </section> <ul data-sourcepos="43:1-44:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">第1层:连接层</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">对来自客户端的连接进行权限验证并将相关的连接信息维护到连接池中,以便于下次连接。</span> </section> <ul data-sourcepos="47:1-48:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">第2层:服务层:</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">提供NoSQL,SQL的API,SQL解析,SQL语句优化,SQL语句缓存等相关组件。</span> </section> <ul data-sourcepos="51:1-52:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">第3层:存储引擎层:</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">提供了一系列可插拔的存储引擎,我们可以通过存储引擎来进行数据的写入与读取,</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">通过存储引擎,我们可以真正的与硬盘中的数据和日志进行交互,</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">我们可以根据需求来选择合适的存储引擎进行使用。</span> </section> <ul data-sourcepos="59:1-60:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">第4层:文件系统层:</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">该层包含了具体的日志文件和数据文件以及MySQL相关的程序。</span> </section> <h2 data-sourcepos="64:1-64:47" style="font-weight: bold;font-size: 22px;margin: 10px auto 5px;border-top-width: 1px;border-top-style: solid;border-top-color: rgb(242, 242, 242);background-color: rgb(242, 242, 242);"><span style="margin-top: -1px;padding-top: 14px;padding-bottom: 14px;padding-right: 5px;padding-left: 5px;font-size: 17px;border-top: 4px solid rgb(33, 33, 34);display: inline-block;line-height: 1.5;font-weight: normal;background-color: rgb(30, 30, 30);border-bottom-right-radius: 100px;color: rgb(255, 255, 255);padding-right: 20px;padding-left: 10px;">1.2 回表(table lookup) 的简单介绍</span></h2> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">回表(table lookup)通常是指数据库查询过程中,需要从索引层查找到某条记录的主键,再通过这个主键回到数据表中获取完整的记录。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">回表操作在数据库系统中的不同层次上实现,而这主要取决于数据库的架构设计。</span> </section> <ol data-sourcepos="70:1-83:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;" class="list-paddingleft-1"> <li> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;"><strong>Server 层(查询层)</strong>:</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">在这一层,数据库接收查询请求并决定如何执行查询。</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">查询优化器会决定是否需要进行回表操作。通过二级索引 查找到记录的主键后,查询层会发出回表的请求。</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">此时,实际的数据读取工作还没有发生。</span> </section></li> <li style="margin-top: 0.25em;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;"><strong>Engine 存储层</strong>:回表的实际数据读取是在存储层完成的。</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">一旦查询层决定需要回表,存储层负责根据主键从存储介质(例如硬盘或内存)中提取相应的完整记录。</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">存储层负责处理物理数据读取、缓存管理、磁盘 I/O 等操作。</span> </section></li> </ol> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">总结来说,回表的决策是在&nbsp;<strong>Server 层</strong>(查询层)做出的,而实际的记录读取则是在&nbsp;<strong>存储层</strong>&nbsp;完成的。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">所以,回表操作涵盖了这两个层面的协作。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <img class="rich_pages wxw-img" data-imgfileid="100019770" data-ratio="0.85" src="/upload/a4586874a085ec6fee2c1002afce88d5.png" data-type="png" data-w="1080" style="box-sizing: content-box;border-style: none;background-color: rgb(255, 255, 255);"> </section> <h2 data-sourcepos="90:1-90:70" style="font-weight: bold;font-size: 22px;margin: 10px auto 5px;border-top-width: 1px;border-top-style: solid;border-top-color: rgb(242, 242, 242);background-color: rgb(242, 242, 242);"><span style="margin-top: -1px;padding-top: 14px;padding-bottom: 14px;padding-right: 5px;padding-left: 5px;font-size: 17px;border-top: 4px solid rgb(33, 33, 34);display: inline-block;line-height: 1.5;font-weight: normal;background-color: rgb(30, 30, 30);border-bottom-right-radius: 100px;color: rgb(255, 255, 255);padding-right: 20px;padding-left: 10px;">1.3 由浅入深,一步一步理解回表查询(table lookup)</span></h2> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;"><strong>在理解回表查询之前,我们需要先了解两个重要的概念:聚集索引和非聚集索引。</strong></span> </section> <h3 data-sourcepos="96:1-96:55" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">基本概念:聚集索引(Clustered Index):</span></h3> <ul data-sourcepos="98:1-102:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">存储方式:聚集索引决定了数据表中数据行的物理存储顺序。索引的顺序与数据行的顺序一致,实际上是直接嵌入到数据表中的一种排序结构。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">影响查询:由于数据行的存储顺序与聚集索引的顺序一致,当通过聚集索引进行查询时,数据库引擎可以更快地定位到所需的数据,因为它知道数据的物理存储位置。适用于范围查询和排序操作。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">唯一性:一个表只能有一个聚集索引,通常是主键,因为主键的值是唯一的。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">存储数据:整个数据行</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <img class="rich_pages wxw-img" data-imgfileid="100019768" data-ratio="0.4685185185185185" src="/upload/337f688d360884f7ed96bee6707b697a.png" data-type="png" data-w="1080" style="box-sizing: content-box;border-style: none;background-color: rgb(255, 255, 255);"> </section> <h3 data-sourcepos="109:1-109:62" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">基本概念:非聚集索引(Non-Clustered Index):</span></h3> <ul data-sourcepos="111:1-122:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;" class="list-paddingleft-1"> <li> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">存储方式:非聚集索引维护了索引键值和指向实际数据行的指针之间的映射关系。</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">索引键值与数据行的物理存储顺序无关,数据行的实际内容可能分散存储在磁盘上。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">影响查询:通过非聚集索引进行查询时,数据库引擎首先根据索引键值找到对应的 指针或引用,然后再根据指针或引用去检索相应的数据行。适用于频繁的搜索和查询,但可能需要额外的IO操作。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">唯一性:一个表可以有多个非聚集索引,不要求索引键值是唯一的。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">存储数据:当前字段的值和指向数据行的指针或引用(通俗的说就是当前字段的主键值 Primary Key)</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <img class="rich_pages wxw-img" data-imgfileid="100019771" data-ratio="0.4685185185185185" src="/upload/e66244dbff5b4cd617c1fa65e32989b8.png" data-type="png" data-w="1080" style="box-sizing: content-box;border-style: none;background-color: rgb(255, 255, 255);"> </section> <h3 data-sourcepos="127:1-127:37" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">使用案例介绍:回表查询</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">回表查询是数据库中常见的一个概念,指的是server层无法直接从索引中获取所需数据,而需要回到原始数据表中进行额外的查找操作。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">为了更好地理解回表查询,让我们通过SQL语句的方式来演示一下。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">假设我们有一个包含员工信息的表 employees,其中包括:</span> </section> <ul data-sourcepos="135:1-139:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">员工的编号(employee_id)</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">姓名(name)</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">部门(department)</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">薪水(salary)等字段。</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">这边把 employee_id 作为ID 主键,也就是 聚集索引,以加快根据员工编号进行查询的速度。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">首先来一个没有回表的查询:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">现在,假设我们需要查询员工编号为 1001 的员工的薪水,我们可能会编写如下的SQL查询语句:</span> </section> <pre data-sourcepos="148:1-151:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, &quot;Liberation Mono&quot;, Courier, &quot;Courier New&quot;, Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;"><span style="color: rgb(1, 86, 146);">SELECT</span> salary <span style="color: rgb(1, 86, 146);">FROM</span> employees <span style="color: rgb(1, 86, 146);">WHERE</span> employee_id = <span style="color: rgb(183, 85, 1);">100</span>;<br><br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">在这个查询中,server层 通过 Engine 利用 employee_id 上的聚集索引,快速地找到对应的员工corde记录,并返回薪水信息,这时候,就不会发生回表查询。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">再来一个没有回表的查询:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">如果我们需要在name列查询员工姓名为 令狐冲 的薪水,并且假设 name 存在一个idx_name 的非聚集索引 :</span> </section> <pre data-sourcepos="163:1-166:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, &quot;Liberation Mono&quot;, Courier, &quot;Courier New&quot;, Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;"><span style="color: rgb(1, 86, 146);">SELECT</span> salary <span style="color: rgb(1, 86, 146);">FROM</span> employees <span style="color: rgb(1, 86, 146);">WHERE</span> <span style="color: rgb(1, 86, 146);">name</span>= <span style="color: rgb(84, 121, 13);">'令狐冲'</span>;<br><br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">那么数据库server层 通过 Engine 利用 idx_name 非聚集索引,查到 令狐冲的id 为100。server层 再通过 Engine 利用 employee_id 上的聚集索引,快速地找到100 对应的员工recode记录,这就导致了回表查询。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <img class="rich_pages wxw-img" data-imgfileid="100019769" data-ratio="0.774074074074074" src="/upload/7aeab8144edfbbcf0af95a34dd68cd4d.png" data-type="png" data-w="1080" style="box-sizing: content-box;border-style: none;background-color: rgb(255, 255, 255);"> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">回表通常发生在:</span> </section> <ul data-sourcepos="178:1-182:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">查询语句中包含了索引无法覆盖的字段</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">或者涉及到了复杂的查询条件时。</span> </section></li> </ul> <h2 data-sourcepos="183:1-183:44" style="font-weight: bold;font-size: 22px;margin: 10px auto 5px;border-top-width: 1px;border-top-style: solid;border-top-color: rgb(242, 242, 242);background-color: rgb(242, 242, 242);"><span style="margin-top: -1px;padding-top: 14px;padding-bottom: 14px;padding-right: 5px;padding-left: 5px;font-size: 17px;border-top: 4px solid rgb(33, 33, 34);display: inline-block;line-height: 1.5;font-weight: normal;background-color: rgb(30, 30, 30);border-bottom-right-radius: 100px;color: rgb(255, 255, 255);padding-right: 20px;padding-left: 10px;">1.4 回表查询带来的 巨大的问题</span></h2> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">回表查询通常出现在使用非聚簇索引或二级索引的场景中,它带来的一些问题主要集中在性能和效率上。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &quot;Apple Color Emoji&quot;, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;line-height: 1.75em;"> <span style="font-size: 15px;">以下是回表查询中的常见问题:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Helvetica, Arial, sans-serif, &

Redis集群slot迁移改造实践

作者:微信小助手

<section style="font-size: 15px;"> <section style="margin: 10px 0% 8px;text-align: left;justify-content: flex-start;display: flex;flex-flow: row;"> <section style="display: inline-block;width: 100%;vertical-align: top;border-left: 3px solid rgb(219, 219, 219);border-bottom-left-radius: 0px;padding-left: 8px;align-self: flex-start;flex: 0 0 auto;"> <section style="color: rgba(0, 0, 0, 0.5);font-size: 14px;text-align: justify;"> <p style="text-wrap: wrap;">作者:来自 vivo 互联网存储团队- Xu Xingbao</p> </section> </section> </section> <p style="text-wrap: wrap;"><br></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: center;"> <section style="display: inline-block;width: 100%;border-width: 1px;border-style: solid;border-color: rgb(160, 160, 160);padding: 10px;"> <section style="text-align: left;"> <section style="text-align: justify;line-height: 1.8;padding-right: 5px;padding-left: 5px;color: rgb(160, 160, 160);"> <p style="text-wrap: wrap;">Redis 集群经常需要进行在线水平扩缩容,实际操作过程中发现迁移期间服务时延剧烈抖动,业务侧感知明显,为了应对以上问题对原生 Redis 集群 slot 迁移功能进行优化改造。</p> </section> </section> </section> </section> <p style="text-wrap: wrap;"><br></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: center;"> <section style="padding: 3px;display: inline-block;border-bottom: 1px solid rgb(65, 94, 255);font-size: 17px;color: rgb(65, 94, 255);"> <p>一、背景介绍</p> </section> </section> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;">Redis 集群服务在互联网公司被广泛使用,众所周知服务集群化可以突破单节点的能力瓶颈,带来规模、可用性、扩展性等多方面的收益。在实际使用 Redis 集群的过程中,发现在进行涉及集群数据迁移的水平扩缩容操作时,业务侧多次反馈 Redis 请求的时延升高问题,甚至发生过扩容操作导致集群节点下线的可用性故障,并进一步引发迁移流程中断、节点间数据脑裂等一系列严重影响,给运维同事带来极大困扰,严重影响线上服务的稳定。</p> <p style="text-wrap: wrap;"><br></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: center;"> <section style="padding: 3px;display: inline-block;border-bottom: 1px solid rgb(65, 94, 255);font-size: 17px;color: rgb(65, 94, 255);"> <p>二、问题分析</p> </section> </section> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;"><span style="font-size: 16px;color: rgb(65, 95, 255);">2.1 原生迁移介绍</span></p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;">Redis 集群功能采用无中心架构设计,集群中各个节点都维护各自视角的集群拓扑并保存自有的分片数据,集群节点间通过 gossip 协议进行信息协调和变更通知。具体来说 Redis 集群数据管理上采用虚拟哈希槽分区机制,将数据的键通过哈希函数映射到 0~16383 整数槽内,此处的槽位在 Redis 集群设计中被称为 slot。这样实际上每一个节点只需要负责维护一部分 slot 所映射的键值数据,slot 就成为 Redis 集群管理数据的基本单位,集群扩缩容本质上就是 slot 信息和 slot 对应数据数据在节点之间的转移。Redis 集群水平扩展的能力就是基于 slot 维度进行实现,具体流程如下图所示。</p> <p style="text-wrap: wrap;"><br></p> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100015561" data-ratio="0.5046082949308756" data-s="300,640" src="/upload/8a85e31f7314e3667c8722ac682550b0.png" data-type="png" data-w="868" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="text-wrap: wrap;"><br></p> <section> <p style="text-wrap: wrap;">上图所示的迁移步骤中,步骤1-2是对待迁移 slot 进行状态标记,方便满足迁移过程中数据访问,步骤3-4是迁移的核心步骤,这两个步骤操作会在步骤5调度下持续不断进行,直到待迁移 slot 的键值数据完全迁移到了目标节点,步骤6会在数据转移完成后进行,主要是发起集群广播消息更新集群内节点 slot 拓扑。</p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;">由于正常的迁移时一个持续的处理过程,不可避免地会出现正在迁移 slot 数据分布于迁移两端地“分裂”状态,这种状态会随着 slot 迁移的流程进行而持续存在。为了保证迁移期间正在迁移的 slot 数据能够正常读写,Redis 集群实现了下图所示的一种 ask-move 机制,如果请求访问正在迁移的 slot 数据,请求首先会按照集群拓扑正常访问到迁移的源节点,如果在源节点查询到数据则正常处理响应请求;如果在源节点没有找到请求所需数据,则会给客户端回复 ASK {ip}:{port}&nbsp; 消息回包。</p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;">Redis 集群智能客户端收到该回包后会按照包内节点信息找到新节点重试命令,但是由于此时目标节点还没有迁移中 slot 的所属权,所以在重试具体命令之前智能客户端会首先向目的节点发送一个 asking 命令,以此保证接下来访问迁移中 slot 数据的请求能被接受处理。由于原生迁移时按照 key 粒度进行的,一个 key 的数据要不存在源节点,要不存在目的节点,所以Redis 集群可以通过实现上述 ask-move 机制,保证迁移期间数据访问的一致性和完整性。</p> </section> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100015560" data-ratio="0.48259860788863107" data-s="300,640" src="/upload/7992129a5110cd84b059d619be93d712.png" data-type="png" data-w="862" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;"><span style="font-size: 16px;color: rgb(65, 95, 255);">2.2 迁移问题分析</span></p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;"><strong>(1)时延分析</strong></p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;">根据上述原生 Redis 集群迁移操作步骤的了解,可以总结出原生迁移功能按照 key 粒度进行的,即不断扫描源节点上正在迁移的 slot 数据并发送数据给目的节点,这是集群数据迁移的核心逻辑。微观来说迁移单个 key 数据对于服务端来说包含以下操作:</p> <p style="text-wrap: wrap;"><br></p> <section style="margin-top: 10px;margin-bottom: 10px;"> <section style="margin-bottom: -2.25em;margin-right: 5px;background-color: rgb(247, 247, 247);"> <section style="padding: 10px;margin-bottom: 5px;"> <section style="text-align: left;"> <ul class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;"> <li><p>序列化待迁移键值对数据;</p></li> <li><p>通过网络连接发送序列化的数据包;<br></p></li> <li><p>等待回复(目标端接收完包并加载成功才会返回);<br></p></li> <li><p>删除本地残留的副本,释放内存。</p></li> </ul> </section> </section> </section> <section style="margin-left: auto;width: 2.25em;height: 2.25em;border-right: 5px solid transparent;border-bottom: 5px solid transparent;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;">上述操作中涉及多个耗费线程处理时长的操作,首先序列化数据是非常耗费 CPU 时间的操作,如果遇到待迁移 key 比较大线程占用时长也会随之恶化,这对于单工作线程的 Redis 服务来说是不可接受的,进一步地网络发送数据到目标节点时会同步等待结果返回,而迁移目的端又会在进行数据反序列化和入库操作后才会向源节点进行结果返回。需要注意的是在迁移期间会不断循环进行以上步骤的操作,而且这些步骤是在工作线程上连续处理的,期间无法对正常请求进行处理,所以此处就会导致服务响应时延持续突刺,这一点可以通过 slowlog 的监控数据得到验证,迁移期间会在 slowlog 抓取到大量的 migrate 和 restore 命令。</p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;"><strong>(2)ask-move 开销</strong></p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;">正常情况下每个正在迁移的 slot 数据都会一段时间内存在数据分布在迁移的两端的情况,迁移期间该 slot 数据访问请求可以通过 ask-move 机制来保证数据一致性,但是不难看出这样的机制会导致单个请求网络访问次数出现成倍的增加,对客户端也存在一定的开销压力。另外,对于可能存在的用户采用 Lua 或者 Pipline 这种需要对单个 slot 内多 key 连续访问的场景,目前大部分集群智能客户端支持有限,可能会遇到迁移期间相关请求不能正常执行的报错。另外需要说明的是,由于 ask-move 机制的只在迁移两端的主节点上能触发,所以迁移期间从节点是不能保证数据请求结果一致性的,这对于采用读写分离方式访问集群数据的用户也非常不友好。</p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;"><strong>(3)拓扑变更开销</strong></p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;">为了降低迁移期间数据 ask-move 的机制对请求的影响,正常情况下原生迁移每次只会操作一个 slot 迁移,这就导致对每一个迁移完成的 slot 都会触发集群内节点进行一次拓扑更新,而每次集群拓扑的更新都会触发正在执行指令的业务客户端几乎同时发送请求寻求更新集群拓扑,拓扑刷新请求结果计算开销高、结果集大,大大增加了节点的处理开销,也会造成正常服务请求时延的突刺,尤其对于连接数较大、集群节点多的集群,集中的拓扑刷新请求很容易造成节点计算资源紧张和网络拥塞,容易触发出各种服务异常告警。</p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;"><strong>(4)迁移无高可用</strong></p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;">原生的迁移的 slot 标记状态只存在于迁移双端的主节点,其对应的从节点并不知道迁移状态,这也就导致一旦在迁移期间发生节点的 failover,迁移流程将会中断和出现 slot 状态残留,也将进一步导致迁移 slot 数据的访问请求无法正常触发 ask-move 机制而发生异常。例如迁移源节点异常,那么其 slave 节点 failover 上线,由于新主节点并不能同步到迁移状态信息,那么对于迁移中 slot 的请求就不能触发 ask 回复,如果是一个对已经迁移至目标节点的数据的写请求,新主节点会直接在本节点新增 key,导致数据出现脑裂,类似地如果处理的是已经迁移数据的读取请求也无法保证返回正确结果。</p> <p style="text-wrap: wrap;"><br></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: center;"> <section style="padding: 3px;display: inline-block;border-bottom: 1px solid rgb(65, 94, 255);font-size: 17px;color: rgb(65, 94, 255);"> <p>三、优化方案</p> </section> </section> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;"><span style="font-size: 16px;color: rgb(65, 95, 255);">3.1 优化方向思考</span></p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;">通过原生数据迁移机制分析,可以发现由于迁移操作涉及大量的同步阻塞操作会长时间占用工作线程,以及频繁的拓扑刷新操作,会导致请求时延不断出现上升。那么是否可以考虑将阻塞工作线程的同步操作改造成为异步线程处理呢?这样改造有非常大的风险,因为原生迁移之所以能够保证迁移期间数据访问的正确性,正是这些同步接口进行了一致性保证,如果改为异步操作将需要引入并发控制,还要考虑迁移数据请求与 slave 节点的同步协调问题,此方案也无法解决拓扑变动开销问题。所以 vivo 自研 Redis 放弃了原生按照 key 粒度进行迁移的逻辑,结合线上真实扩容需求,采用了类似主从同步的数据迁移逻辑,将迁移目标节点伪装成迁移源节点的从节点,通过主从协议来转移数据。</p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;"><span style="font-size: 16px;color: rgb(65, 95, 255);">3.2 功能实现原理</span></p> <p style="text-wrap: wrap;"><br></p> <section> <p style="text-wrap: wrap;">Redis 主从同步机制是指在 Redis 主节点(Master)和从节点(Slave)之间进行数据同步和复制的过程,主从同步机制可以提高 Redis 集群的可用性,避免单点故障和数据丢失等问题。Redis 目前主从同步有全量同步和部分同步两种方式,从节点发送同步位点给主节点,如果是首次同步则需要走全量同步逻辑,主节点通过发送 RDB 基础数据文件和传播增量命令方式将数据同步给从节点;如果不是首次同步,主节点则会通过从节点同步请求中的位点等信息判断是否满足增量同步条件,优先进行增量同步以控制同步开销。由于主节点在同步期间也在持续处理新的命令请求,所以从节点对主节点的数据同步是一个动态追齐的过程,正常情况下,主节点会持续发送写命令给从节点。</p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;">基于同步机制,我们设计实现了一套如下图所示的 Redis 集群数据迁移的功能。迁移数据逻辑主要走的全量同步逻辑,迁移数据和同步数据最大的区别在于,正常情况下需要迁移的是源节点部分 slot 数据,目标节点并不需要复制源节点的全量数据,完全复用同步机制会产生不必要的开销,需要对主从同步逻辑进行修改适配。为了解决该问题,我们对相关逻辑做了一些针对性的改造。首先在同步命令交互上,针对迁移场景增加了迁移节点间 slot 信息交互,从而让迁移源节点获知需要迁移哪些 slot 到哪个节点。另外,我们还对 RDB 文件文件结构按照 slot 顺序进行了调整改造,并且将各个 slot 数据的文件起始偏移量数据作为元数据记录到 RDB 文件尾部固定位置,这样在进行迁移操作的 RDB 传输步骤时就可以方便地索引到 RDB 文件中目标 slot 数据片段。</p> </section> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100015562" data-ratio="0.5502183406113537" data-s="300,640" src="/upload/84433490d059d115b36695266c9c7a99.png" data-type="png" data-w="916" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;"><span style="font-size: 16px;color: rgb(65, 95, 255);">3.3 改造效果分析</span></p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;"><strong>(1)时延影响小</strong></p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;">对于 slot 迁移操作而言,主要涉及迁移源和目的两端的开销,对于基于主从同步机制实现的新 slot 迁移,其源节点主要开销在于生成 RDB 和传送网络包,正常对于请求时延影响不大。但是因为目的节点需要对较大的 RDB 文件片段数据进行接收、加载,由于目的节点迁移时也需要对正常服务请求响应,此时不再能采用类似 slave 节点将所有数据收取完以后保存本地文件,然后进行阻塞式数据加载的方案,所以新 slot 迁移功能对迁移目的节点的数据加载流程进行了针对性改造,目的节点会按照接收到的网络包粒度将数据按照下图所示进行递进式加载,即 slot 迁移目标节点每接收完一个 RDB 数据网络包就会尝试加载,每次只加载本次网络包内包含的完整元素,这样复合类型数据就可以按照 field 粒度加载,从而降低多元素大 key 数据迁移对访问时延的剧烈影响。通过这样的设计保持原来单线程简洁架构的同时,有效地控制了时延影响,所有数据变更操作都保持在工作线程进行,不需要进行并发控制。通过以上改造,基本消除了迁移大 key 对迁移目的节点时延影响。</p> <p style="text-wrap: wrap;"><br></p> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100015559" data-ratio="0.37142857142857144" data-s="300,640" src="/upload/5c8d96b97f278dd66c27a275129fe95d.png" data-type="png" data-w="1050" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;"><strong>(2)数据访问稳定</strong></p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;">新 slot 迁移操作期间,正在迁移的数据还是存储在源节点上没有变,请求继续在源节点上正常处理,用户侧的请求不会触发 ask-move 转发机制。这样用户就不需要担心读写分离会出现数据不一致现象,在进行事务、pipeline 等方式封装执行命令时也不会出现大量请求报错的问题。迁移动作一旦完成,残留在源端的已迁移 slot 数据将成为节点的残留数据,这部分数据不会再被访问,对上述残留数据的清理被设计在 serverCron 中逐步进行,这样每一次清理多少数据可以参数化控制,可以根据需要进行个性化设置,保证数据清理对正常服务请求影响完全可控。</p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;"><strong>(3)拓扑变更少</strong></p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;">原生的迁移功能为了降低 ask-move 机制对正常服务请求的影响,每次仅会对一个 slot 进行数据迁移,迁移完了会立即发起拓扑变更通知来集群节点转换 slot 的属主,这就导致拓扑变化的次数随着迁移 slot 的数量增加而变多,客户端也会在每一次感知到拓扑变化后发送命令请求进行拓扑更新。更新拓扑信息的命令计算开销较大,如果多条查询拓扑的命令集中处理,就会导致节点资源的紧张。新的 slot 迁移按照节点进行数据同步,可以支持同时迁移源节点的多个 slot 甚至全部数据,最后可以通过一次拓扑变更转换多个 slot 的属主,大大降低了拓扑刷新的影响。<br></p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;"><strong>(4)支持高可用</strong></p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;">集群的数据迁移是一个持续的过程,这个过程可能长达几个小时,期间服务可能发生各种异常情况。正常情况下的 Redis 集群具有 failover 机制,从节点可感知节点异常以代替旧主节点进行服务。新 slot 迁移功能为了应对这样的可用性问题,将 slot 迁移状态同步给从节点,这样迁移期间如果集群迁移节点发生 failover,其从节点就可以代替旧主节点继续推进数据迁移流程,保证了迁移流程的高可用能力,避免人工干预,大大简化运维操作复杂度。<br></p> <p style="text-wrap: wrap;"><br></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: center;"> <section style="padding: 3px;display: inline-block;border-bottom: 1px solid rgb(65, 94, 255);font-size: 17px;color: rgb(65, 94, 255);"> <p>四、功能测试对比</p> </section> </section> <p style="text-wrap: wrap;"><br></p> <section style="text-align: unset;color: rgb(62, 62, 62);"> <p>为了验证改造后迁移功能的效果,对比自研迁移和原生迁移对请求响应的影响,在三台同样配置物理机上部署了原生和自研两套相同拓扑的集群,选择后对 hash 数据类型的 100k 和 1MB 两种大小数据分别进行了迁移测试,每轮在节点间迁移内存用量 5G 左右的数据。测试主要目的是对比改造前后数转移对节点服务时延影响,所以在实际测试时没有对集群节点进行背景流量操作,节点的时延数据采用每秒钟 ping 10次节点的方式进行采集,迁移期间源节点和目的节点的时延监控数据入下表所示(纵轴数值单位:ms)。</p> </section> <p style="text-wrap: wrap;"><br></p> <section style="margin: 10px 0%;"> <section style="display: inline-block;width: 100%;vertical-align: top;overflow-x: auto;"> <section style="overflow: hidden;width: 150%;max-width: 150% !important;"> <section style="display: inline-block;vertical-align: middle;width: 100%;"> <section style="justify-content: flex-start;display: flex;flex-flow: row;"> <section style="display: inline-block;width: 100%;vertical-align: top;align-self: flex-start;flex: 0 0 auto;"> <section style="text-align: center;margin-right: 0%;margin-left: 0%;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100015563" data-ratio="0.4703703703703704" data-s="300,640" src="/upload/693b08faf103636cca6494785202cee2.jpg" data-type="jpeg" data-w="1080" style="vertical-align: middle;width: 100%;"> </section> </section> </section> </section> </section> </section> </section> </section> <section style="text-align: center;font-size: 13px;"> <p>(左右滑动查看更多)</p> </section> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;">通过对比以上原生和自研集群 slot 迁移期间的时延监控数据,可以看出自研 slot 迁移功能迁移数据期间迁移两端节点的请求响应时延表现非常平稳,也可以表现出经过主从复制原理改造的 Redis 集群 slot 迁移功能具备的优势和价值。</p> <p style="text-wrap: wrap;"><br></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: center;"> <section style="padding: 3px;display: inline-block;border-bottom: 1px solid rgb(65, 94, 255);font-size: 17px;color: rgb(65, 94, 255);"> <p>五、总结和展望</p> </section> </section> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;">原生 Redis 集群的扩缩容功能按照 key 粒度进行数据转移,较大的 key 会造成工作线程的长时间占用,进而引起正常服务请求时延飙高问题,甚至导致节点长时间无法回复心跳包而被判定下线的情况,存在稳定性风险。通过同步机制改造实现的新 slot 迁移功能,能显著降低数据迁移对用户访问时延的影响,提升线上 Redis 集群稳定性和运维效率,同时新的 slot 迁移功能还存在一些问题,例如新的迁移造成节点频繁的 bgsave 压力,迁移期间节点内存占用增加等问题,未来我们将围绕这些具体问题,继续不断优化总结。</p> <p style="text-wrap: wrap;"><br></p> <section style="margin-right: 0%;margin-bottom: 20px;margin-left: 0%;justify-content: flex-start;display: flex;flex-flow: row;"> <section style="display: inline-block;vertical-align: middle;width: 40%;align-self: center;flex: 0 0 auto;"> <section style="margin-top: 0.5em;margin-bottom: 0.5em;"> <section style="border-top: 1px dotted rgb(90, 98, 114);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> <section style="display: inline-block;vertical-align: middle;width: 20%;align-self: center;flex: 0 0 auto;"> <section style="text-align: center;color: rgb(45, 66, 87);font-size: 11px;"> <p>END</p> </section> </section> <section style="display: inline-block;vertical-align: middle;width: 40%;align-self: center;flex: 0 0 auto;"> <section style="margin-top: 0.5em;margin-bottom: 0.5em;"> <section style="border-top: 1px dotted rgb(90, 98, 114);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> <section style="margin-top: 10px;margin-bottom: 10px;text-align: left;"> <section style="padding-left: 1em;padding-right: 1em;display: inline-block;text-align: center;"> <span style="display: inline-block;padding: 0.3em 0.5em;border-radius: 0.5em;background-color: rgb(65, 94, 255);color: rgb(255, 255, 255);" title="" opera-tn-ra-cell="_$.pages:0.layers:0.comps:86.title1"><p>猜你喜欢</p></span> </section> <section style="border-width: 1px;border-style: solid;border-color: transparent;margin-top: -1em;padding: 20px 10px 10px;background-color: rgb(239, 239, 239);text-align: center;"> <section style="font-size: 14px;text-align: left;"> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzI4NjY4MTU5Nw==&amp;mid=2247498871&amp;idx=1&amp;sn=1edcfe3817adf006c8ef1ec4c6fdc2a2&amp;chksm=ebdb8ce5dcac05f3b5a802886cf84b8dff7c73b14d8a3fe7c371c701b0053fd38c8b7363d6d9&amp;scene=21#wechat_redirect" textvalue="TiKV 源码分析之 PointGet" linktype="text" imgurl="" imgdata="null" data-itemshowtype="0" tab="innerlink" data-linktype="2">TiKV 源码分析之 PointGet</a></p> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzI4NjY4MTU5Nw==&amp;mid=2247499108&amp;idx=1&amp;sn=6904feec20d690a2f102795f22c7bc65&amp;chksm=ebdb8df6dcac04e039af9a47569217b2bbc87bb5b68c8f668baed8a8cd1e12e5fb7e03c395fa&amp;scene=21#wechat_redirect" textvalue="MySQL 5.7 DDL 与 GH-OST 对比分析" linktype="text" imgurl="" imgdata="null" data-itemshowtype="0" tab="innerlink" data-linktype="2">MySQL 5.7 DDL 与 GH-OST 对比分析</a></p> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzI4NjY4MTU5Nw==&amp;mid=2247498950&amp;idx=1&amp;sn=3cebd18bb2014db6d64e1a63e78bdae4&amp;chksm=ebdb8c54dcac0542affae41abdd7aae3e7fb7df37444ee8fe877a606ae125781de59a9e1c2fb&amp;scene=21#wechat_redirect" textvalue="数据特征采样在 MySQL 同步一致性校验中的实践" linktype="text" imgurl="" imgdata="null" data-itemshowtype="0" tab="innerlink" data-linktype="2">数据特征采样在 MySQL 同步一致性校验中的实践</a></p> </section> </section> </section> </section> <section class="mp_profile_iframe_wrp"> <mp-common-profile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-id="MzI4NjY4MTU5Nw==" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/4g5IMGibSxt45QXJZicZ9gaNU2mRSlvqhQd94MJ7oQh4QFj1ibPV66xnUiaKoicSatwaGXepL5sBDSDLEckicX1ttibHg/0?wx_fmt=png" data-nickname="vivo互联网技术" data-alias="vivoVMIC" data-signature="分享 vivo 互联网技术干货与沙龙活动,推荐最新行业动态与热门会议。" data-from="0" data-is_biz_ban="0"></mp-common-profile> </section> <p style="display: none;"> <mp-style-type data-value="3"></mp-style-type></p>

分享9条高频SQL优化技巧

作者:微信小助手

<blockquote style="margin-top: 10px;margin-bottom: 10px;border-left-width: 5px;border-left-color: rgb(255, 69, 0);color: rgba(0, 0, 0, 0.5);font-size: 16px;line-height: 1.75;text-wrap: wrap;letter-spacing: normal;text-align: left;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;border-radius: 5px;background: rgb(255, 245, 245);padding-top: 5px !important;padding-right: 10px !important;padding-bottom: 5px !important;"></blockquote>

微服务重构:Mysql+DTS+Kafka+ElasticSearch解决跨表检索难题

作者:微信小助手

<h1 data-mpa-powered-by="yiban.io"><img class="rich_pages wxw-img" data-imgfileid="100029878" data-ratio="1" src="/upload/7147f503f5cb840c509eeb760fd1ad23.jpg" data-type="jpeg" data-w="1024"></h1> <h1><span style="color: rgb(172, 57, 255);"><strong><span style="font-size: 24px;">1、背景</span></strong></span></h1> <p><span style="font-size: 15px;">在微服务拆分过程里,会对数据库模块重新进行建模拆分,导致部分表和数据,出现物理隔离,导致跨库JOIN的SQL不可行,并在数据检索上也有性能损耗的风险。下面我们来一起探讨一下,具体的解决方案。</span></p> <h2><strong><span style="font-size: 20px;color: rgb(61, 167, 66);">1.1 方案比较</span></strong></h2> <p style="font-size: 15px;"><span style="font-size: 15px;">业界一般解决方案包括不限于下面几个</span></p> <table data-ace-table-col-widths="157;170;218;233"> <colgroup> <col width="157"> <col width="170"> <col width="218"> <col width="233"> </colgroup> <thead> <tr st

美团面试:Redis锁如何续期?Redis锁超时,任务没完怎么办?

作者:微信小助手

<section data-tool="mdnice编辑器" data-website="https://www.mdnice.com"> <h2 data-tool="mdnice编辑器" style="font-weight: bold;font-size: 22px;margin: 10px auto 5px;border-top: 1px solid rgb(242, 242, 242);background-color: rgb(242, 242, 242);"><span style="margin-top: -1px;padding-top: 14px;padding-bottom: 14px;padding-right: 5px;padding-left: 5px;font-size: 17px;border-top: 4px solid rgb(33, 33, 34);display: inline-block;line-height: 1.5;font-weight: normal;background-color: rgb(30, 30, 30);border-bottom-right-radius: 100px;color: rgb(255, 255, 255);padding-right: 20px;padding-left: 10px;">本文目录</span></h2> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><strong><span style="font-size: 14px;">-&nbsp;</span></strong></strong><strong>尼恩说在前面</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><span style="font-size: 14px;">-&nbsp;</span></strong>Redis分布式锁过期怎么办?</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><span style="font-size: 14px;">-&nbsp;</span></strong>两大Redis 分布式</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>分布式锁一般有如下的特点:</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><strong><span style="font-size: 14px;">-&nbsp;</span></strong></strong><strong>基于Jedis 的API实现分布式锁</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>Redis几种架构</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>首先看两个命令:</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>基于Jedis API的分布式锁的总体流程:</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>简单加锁:使用set的命令时,同时设置过期时间</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>基于Jedis 的API实现简单解锁代码</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><strong><span style="font-size: 14px;">-&nbsp;</span></strong></strong><strong>基于Lua脚本实现分布式锁</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>lua脚本的好处</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>基于纯Lua脚本的分布式锁的执行流程</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>加锁的Lua脚本:lock.lua</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>解锁的Lua脚本:unlock.lua:</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>两个文件,放在资源文件夹下备用:</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><strong><span style="font-size: 14px;">-&nbsp;</span></strong></strong><strong>在Java中调用lua脚本,完成加锁操作</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>在Java中调用lua脚本,完成加锁操作</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>通过实现JUC的显示锁Lock接口,实现一个简单的分布式锁</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>编写RedisLockService用于管理JedisLock</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>测试用例</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><strong><span style="font-size: 14px;">-&nbsp;</span></strong></strong><strong>STW导致的锁过期问题</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>锁过期问题 的解决方案</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>方式一:模拟CAS乐观锁的方式,增加版本号</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>方式二:watch dog自动延期机制</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>为啥推荐使用Redission</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><strong><span style="font-size: 14px;">-&nbsp;</span></strong></strong><strong>Redisson简介</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>Redisson与Jedis的对比</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>Redission 的源码地址:</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>特性 &amp; 功能:</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><strong><span style="font-size: 14px;">-&nbsp;</span></strong></strong><strong>Redisson的使用</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>如何安装 Redisson</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>获取RedissonClient对象</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>SpringBoot整合Redisson</p> <h5 data-sourcepos="299:1-299:178" style="letter-spacing: 0.578px;white-space: normal;"><span style="font-size: 14px;letter-spacing: 0.578px;">&nbsp; &nbsp; -</span><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.034em;">一、导入Maven依赖</span></h5> <h5 data-sourcepos="299:1-299:178" style="letter-spacing: 0.578px;white-space: normal;"><span style="font-size: 14px;letter-spacing: 0.578px;">&nbsp; &nbsp; -</span><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.034em;">二、核心配置文件</span></h5> <h5 data-sourcepos="299:1-299:178" style="letter-spacing: 0.578px;white-space: normal;"><span style="font-size: 14px;letter-spacing: 0.578px;">&nbsp; &nbsp; -</span><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.034em;">三、添加配置类</span></h5> <h5 data-sourcepos="299:1-299:178" style="letter-spacing: 0.578px;white-space: normal;"><span style="font-size: 14px;letter-spacing: 0.578px;">&nbsp; &nbsp; -</span><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.034em;">自定义starter</span></h5> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>使用 RLock 实现 Redis 分布式锁</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><strong><span style="font-size: 14px;">-&nbsp;</span></strong></strong><strong>Redision锁 核心源码分析</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>getLock()方法</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>tryLock方法</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>tryAcquire()方法</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>tryLockInnerAsync</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>原理:加锁机制</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>Lua脚本的详解</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>关于 lua脚本的参数解释:</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>锁互斥机制</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>可重入加锁机制</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>释放锁机制<span style="display: none;line-height: 0px;">‍</span><span style="display: none;line-height: 0px;">‍</span></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>unlock 源码</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>unlockInnerAsync方法</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>原理:Redision 解锁机制</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><span style="font-family: &quot;Helvetica Neue&quot;;font-size: 14px;letter-spacing: 0.578px;">&nbsp;-&nbsp;</span>通过redis Channel 解锁订阅</p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><strong><span style="font-size: 14px;">-&nbsp;</span></strong></strong><strong>watch dog自动延期机制</strong></p> <p style="font-stretch: normal;font-size: 13px;font-family: &quot;Helvetica Neue&quot;;"><strong><strong style="font-family: &quot;Helvetica Neue&quot;;font-size: 13px;letter-spacing: 0.578px;white-space: normal;"><span style="font-size: 14px;">-&nbsp;</span></strong>使用watchDog机制实现锁的续期

B站是如何实施全链路Trace追踪的?

作者:微信小助手

<section style="line-height: 1.6;font-size: 16px;margin-bottom: 24px;"> <section style="margin-top: 10px;margin-bottom: 10px;text-align: center;"> <section style="display: inline-block;vertical-align: top;padding-left: 10px;"> <section style="border-bottom: 1px dashed rgb(0, 0, 0);padding-left: 5px;font-size: 20px;color: rgb(12, 182, 242);"> <p><strong>一、</strong><strong>概述</strong></p> </section> <section style="margin-top: -7px;margin-left: -10px;width: 10px;"> <section style="transform: rotate(0deg);margin-left: auto;width: 7px;height: 7px;background-color: rgb(255, 102, 149);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> <section style="margin-top: -4px;margin-left: -3px;width: 10px;height: 10px;background-color: rgb(12, 182, 242);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">直播业务具有实时性强,复杂度高,排查链路长,影响面大等特征,线上问题如果不能立刻排查处理,分分秒秒都在影响用户的观看体验、主播的收入。</p> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">但各端的问题可能都只是表象,例如,一个看似简单的画面卡顿问题,可能涉及到编码器配置、网络带宽分配、服务器负载等多个方面,各个团队经常在等待合作方的反馈,一整套流程下来,一个线上问题的定位可能要消耗掉数小时的人力。</p> <p style="word-break: break-all;white-space: normal;"><strong>我们迫切的需要一套高效的跨端实时排障系统!</strong></p> </section> <p style="white-space: normal;"><br></p> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100016735" data-ratio="0.562962962962963" data-s="300,640" src="/upload/cbf58f7f2368899bda904d8704bb9eb6.png" data-type="png" data-w="1080" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;"><strong>为此我们采取了以下措施:</strong></p> <ol class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;"> <li><p style="word-break: break-all;margin-bottom: 15px;"><strong>关键业务监控:</strong>联合各协作方,对关键业务的接口、广播和核心处理逻辑实施了实时埋点监控,并附加了相关场景信息,确保了问题定位的准确性和全面性。</p></li> <li><p style="word-break: break-all;margin-bottom: 15px;"><strong>统一追踪系统:</strong>为了实现单个业务链路所有埋点的跨端联络,我们设计了统一的trace_id字段,并在数据层进行串联,通过看板直观展示,极大地提升了问题追踪和定位的效率。</p></li> </ol> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;"><strong>这些措施带来了显著的成效:</strong></p> <ul class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;"> <li><p style="word-break: break-all;margin-bottom: 15px;"><strong>跨部门协作效率提升:</strong>通过实时数据共享和统一追踪系统,直播移动端、PC端、Web端、服务端以及流媒体等各个团队协作效率大幅提升。在开播、视频连线等9个核心业务的故障排查中,排障率达到了91%,异常定位的平均时间从2小时缩短至仅需5分钟。兄弟部门也采纳了我们的方案,有效减轻了工作压力。</p></li> <li><p style="word-break: break-all;margin-bottom: 15px;"><strong>系统稳定性增强:</strong>这些措施还帮助我们优化了开播异常断流、连麦发布订阅失败等多项关键业务问题,确保了系统的高效运行,减少了因技术问题导致的用户流失。</p></li> <li><p style="word-break: break-all;"><strong>用户体验改善:</strong>我们的快速响应和问题解决能力极大地提升了主播和用户的直播体验。用户和主播的正面反馈络绎不绝,间接提高了主播收入稳定性,增强了平台的吸引力。</p></li> </ul> </section> <p style="white-space: normal;"><br></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: center;"> <section style="display: inline-block;vertical-align: top;padding-left: 10px;"> <section style="border-bottom: 1px dashed rgb(0, 0, 0);padding-left: 5px;font-size: 20px;color: rgb(12, 182, 242);"> <p><strong>二、</strong><strong>技术方案详解</strong></p> </section> <section style="margin-top: -7px;margin-left: -10px;width: 10px;"> <section style="transform: rotate(0deg);margin-left: auto;width: 7px;height: 7px;background-color: rgb(255, 102, 149);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> <section style="margin-top: -4px;margin-left: -3px;width: 10px;height: 10px;background-color: rgb(12, 182, 242);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> <p style="white-space: normal;"><br></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: left;"> <section style="display: inline-block;"> <section style="width: 0.7em;height: 0.7em;margin-right: 5px;margin-top: 0.5em;display: inline-block;vertical-align: top;background-color: rgb(255, 102, 149);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> <section style="display: inline-block;vertical-align: top;text-align: center;font-size: 18px;color: rgb(12, 182, 242);"> <p><strong>1. 方案设计</strong></p> </section> </section> </section> <p style="white-space: normal;"><br></p> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100016733" data-ratio="0.3509259259259259" data-s="300,640" src="/upload/21979d7f31d937bbc9ccc2106c7dc826.jpg" data-type="jpeg" data-w="1080" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">如上图所示,整体全链路排障建设可以分为数据采集、数据处理&amp;存储、可视化工具建设3大块。</p> <p style="word-break: break-all;white-space: normal;">在开始介绍实现方案之前,需要简单介绍一下OpenTracing,它是业内实现分布式链路追踪系统通常会采用的方案,我们在后续的埋点和上报组件设计也对它进行了一些参考。OpenTracing定义了追踪数据所需要的操作和数据结构,帮助开发人员实现分布式追踪的能力。OpenTracing里面有两个比较核心的概念,简单说明一下:</p> </section> <p style="white-space: normal;"><br></p> <section style="text-align: left;justify-content: flex-start;display: flex;flex-flow: row nowrap;margin-top: 5px;margin-bottom: 10px;"> <section style="display: inline-block;width: 100%;vertical-align: top;align-self: flex-start;flex: 0 0 auto;background-color: rgba(234, 244, 255, 0.34);padding: 25px;height: auto;"> <section style="transform: translate3d(-5px, 0px, 0px);"> <section style="text-align: justify;padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">Trace:Trace代表一条追踪路径,它由多个Span组成,存在一个唯一ID</p> <p style="word-break: break-all;white-space: normal;">Span:Span代表追踪路径中的一个时间跨度,包括操作名称、开始时间、结束时间等信息,由SpanID作为标识。由多个 Span 可以形成一条追踪路径。Span还定义了父子、跟随两种关系。在Span上下文中,记录和维护了Trace的ID和当前Span的ID。</p> </section> </section> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;white-space: normal;">下图是OpenTracing的模型图,它描述了由多个Span组成一条追踪路径:</p> </section> <p style="white-space: normal;"><br></p> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100016731" data-ratio="0.2833333333333333" data-s="300,640" src="/upload/468548c08d0f7e5922c4768173d74b9f.png" data-type="png" data-w="1080" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">OpenTracing在服务端得到了广泛的使用,但是面临客户端业务现状和问题,我们调整了最终方案的实现方式</p> <ol class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;"> <li><p style="word-break: break-all;margin-bottom: 15px;">直播场景用户行为一般都是即时操作,时间片段的设计并太不合适</p></li> <li><p style="word-break: break-all;margin-bottom: 15px;">OpenTracing是跨编程语言的标准,一些API的设计比较抽象,在业务中使用不友好</p></li> </ol> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">考虑到这些,我们借鉴了OpenTracing中核心的概念:trace_id和事件上下文,并简化了OpenTracing中Span的概念,尝试复用端上已有的埋点,扩展字段来实现全链路Trace的能力。下面我们开始介绍。</p> <p style="word-break: break-all;white-space: normal;">首先要确认的是必须上报的埋点字段。为了减轻理解和上报的成本,在设计上我们希望尽可能简单。实际上,这些字段的设计也是为了解决几个关键的问题:</p> </section> <p style="white-space: normal;"><br></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: left;"> <section style="display: inline-block;"> <section style="width: 0.7em;height: 0.7em;margin-right: 5px;margin-top: 0.5em;display: inline-block;vertical-align: top;background-color: rgb(255, 102, 149);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> <section style="display: inline-block;vertical-align: top;text-align: center;color: rgb(12, 182, 242);"> <p><strong>1.1 如何将各端的埋点关联起来?</strong></p> </section> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;white-space: normal;"><strong>trace_id:</strong>一个复杂的事件链路往往并不是单端闭环的。拿邀请上麦举例,它涉及到主播客户端A -&gt; 业务服务 -&gt; 广播服务 -&gt; 观众客户端B -&gt; RTC。我们希望将这一次事件链路中相关的日志都能聚合起来呈现,而不是各端查各端的。为了解决这个问题,我们生成一个全链路都会透传的唯一ID,在每个端的上报中都会携带这个ID,然后通过这个ID,把这次事件关联的上报检索出来,一起展示。</p> </section> <p style="white-space: normal;"><br></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: left;"> <section style="display: inline-block;"> <section style="width: 0.7em;height: 0.7em;margin-right: 5px;margin-top: 0.5em;display: inline-block;vertical-align: top;background-color: rgb(255, 102, 149);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> <section style="display: inline-block;vertical-align: top;text-align: center;color: rgb(12, 182, 242);"> <p><strong>1.2 如何解决日志中缺失的上下文?</strong></p> </section> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;white-space: normal;"><strong>extends:</strong>我们在上报中增加了扩展数据,用于携带上下文以及自己关心的信息,同时在可视化工具中展示出来。</p> </section> <p style="white-space: normal;"><br></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: left;"> <section style="display: inline-block;"> <section style="width: 0.7em;height: 0.7em;margin-right: 5px;margin-top: 0.5em;display: inline-block;vertical-align: top;background-color: rgb(255, 102, 149);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> <section style="display: inline-block;vertical-align: top;text-align: center;color: rgb(12, 182, 242);"> <p><strong>1.3 如何快速的找到异常的环节?</strong></p> </section> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;white-space: normal;"><strong>level:</strong>我们给每一个上报定义了3种状态,正常、警告和异常。在可视化工具中,针对警告和异常状态的上报,用黄色和红色展示出来,这样可以第一时间定位到出现问题的地方,找到负责的端和同学。</p> </section> <p style="white-space: normal;"><br></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: left;"> <section style="display: inline-block;"> <section style="width: 0.7em;height: 0.7em;margin-right: 5px;margin-top: 0.5em;display: inline-block;vertical-align: top;background-color: rgb(255, 102, 149);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> <section style="display: inline-block;vertical-align: top;text-align: center;color: rgb(12, 182, 242);"> <p><strong>1.4 如何衡量这次的事件是否正常?</strong></p> </section> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;"><strong>type:</strong>我们给每一个上报节点定义了3种类型,起始、过程和结束。一次事件执行中,会有一个起始节点,一个结束节点和多个过程节点。如果这次事件执行链路里面,有结束节点,并且所有节点的状态都是正常的,那我们就认为这次事件执行是正常,否则就是异常的</p> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">到这里,最主要的埋点字段就介绍完了,接下来就只需要各端在关键路径上添加上报即可。</p> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;"><br></p> <p style="word-break: break-all;white-space: normal;">在上线验证阶段,移动端先通过透传trace_id的方式快速上线并打通了整条链路,验证了可行性。但是这种方式弊端很大,代码入侵严重而且健壮性差,对于业务同学来说这是非常劝退的,所以我们针对上报组件做了一些设计,目的是降低接入和维护成本,减少代码入侵。</p> </section> <p style="white-space: normal;"><br></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: left;"> <section style="display: inline-block;"> <section style="width: 0.7em;height: 0.7em;margin-right: 5px;margin-top: 0.5em;display: inline-block;vertical-align: top;background-color: rgb(255, 102, 149);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> <section style="display: inline-block;vertical-align: top;text-align: center;font-size: 18px;color: rgb(12, 182, 242);"> <p><strong>2. 上报组件设计</strong></p> </section> </section> </section> <p style="white-space: normal;"><br></p> <section style="text-align: left;justify-content: flex-start;display: flex;flex-flow: row nowrap;margin-top: 5px;margin-bottom: 10px;"> <section style="display: inline-block;width: 100%;vertical-align: top;align-self: flex-start;flex: 0 0 auto;background-color: rgba(234, 244, 255, 0.34);padding: 25px;height: auto;"> <section style="transform: translate3d(-5px, 0px, 0px);"> <section style="text-align: justify;padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;white-space: normal;">上报组件随项目发展共迭代了三个版本,每一版都比上一版更加易用和完善。下面介绍我们的迭代过程,共分为“快速验证可行性”、“大幅提升易用性” 和 “继续增强鲁棒性”。</p> </section> </section> </section> </section> <p style="white-space: normal;"><br></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: left;"> <section style="display: inline-block;"> <section style="width: 0.7em;height: 0.7em;margin-right: 5px;margin-top: 0.5em;display: inline-block;vertical-align: top;background-color: rgb(255, 102, 149);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> <section style="display: inline-block;vertical-align: top;text-align: center;color: rgb(12, 182, 242);"> <p><strong>2.1 快速验证可行性</strong></p> </section> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">在项目初期,为了快速验证链路可行性,上报组件未做过多设计,仅实现了最基础的功能:</p> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">将上述的基础字段(trace_id, level, type等)、业务方自定义参数以及公共参数(房间信息、网络、推流、设备、外设情况、线程id等)进行上报。</p> <p style="word-break: break-all;white-space: normal;">在最初版中,我们将所有的非公共参数都写到了函数入参中,并在业务层透传了trace_id。如图所示:</p> </section> <p style="white-space: normal;"><br></p> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100016734" data-ratio="0.3731481481481482" data-s="300,640" src="/upload/61329be1402111a761e9386e7feebafe.png" data-type="png" data-w="1080" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="white-space: normal;"><br></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: left;"> <section style="display: inline-block;"> <section style="width: 0.7em;height: 0.7em;margin-right: 5px;margin-top: 0.5em;display: inline-block;vertical-align: top;background-color: rgb(255, 102, 149);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> <section style="display: inline-block;vertical-align: top;text-align: center;color: rgb(12, 182, 242);"> <p><strong>2.2 大幅提升易用性</strong></p> </section> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;"><span style="color: rgb(255, 102, 149);"><strong>2.2.1 快速方案遇到的问题</strong></span></p> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">基础功能上线后,验证了我们通过trace_id串联起多个埋点的想法是可行的。随着越来越多的业务接入,显而易见的两个问题便浮上水面:</p> <ol class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;"> <li><p style="word-break: break-all;margin-bottom: 15px;"><strong>上报代码过于繁杂:</strong>由于需要8个参数,需要多行代码才能完成一次上报,在业务代码中插入这一块又一块的和业务无关的代码,会严重降低可读性和可维护性;</p></li> <li><p style="word-break: break-all;margin-bottom: 15px;"><strong>业务入侵性大:</strong>在低耦合的代码架构下,一个功能点的实现经常横跨1~3个模块、纵深5~10层方法调用,想要做到精确的全链路追踪,势必要将trace_id透传,这样就需要在每个方法的入参都增加一个trace_id的参数,不仅写起来麻烦,还对业务的入侵性巨大;</p></li> </ol> <p style="word-break: break-all;white-space: normal;">这里举两个实际的代码例子:</p> </section> <p style="white-space: normal;"><br></p> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100016732" data-ratio="0.31296296296296294" data-s="300,640" src="/upload/31659e8508d8dda1da23d06d936a6262.png" data-type="png" data-w="1080" style="vertical-align: middle;width: 100%;"> </section> </section> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100016740" data-ratio="0.24722222222222223" data-s="300,640" src="/upload/116a99ba67e145e89592fb0788cdd507.png" data-type="png" data-w="1080" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">接下来我们就这两个问题对埋点组件进行优化:</p> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;"><br></p> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;"><span style="color: rgb(255, 102, 149);"><strong>2.2.2 解决埋点代码冗长</strong></span></p> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">需要在业务层和上报层中间插入一个埋点聚合层,负责组装参数,并针对每一个节点向外提供一个简明的方法,在业务层就只需要一行简短的代码就可以完成上报了。</p> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">在埋点聚合层中,我们也做了一些简单的设计,旨在减少业务方的代码量:</p> <ol class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;"> <li><p style="word-break: break-all;margin-bottom: 15px;">尽力减少上报方法传参的数量,将需要的参数都封装进一个事件模型类中,并针对起始节点提供便利构造方法。且将入参node_type、trace_id、level、extends字段加上默认值,这样对于大部分的节点,就不再需要携带所有的参数了。</p></li> <li><p style="word-break: break-all;margin-bottom: 15px;">针对每个业务类型都额外做了一层封装,这样就不用每次都填写event_type字段了,进一步的减少了代码量。至此,对于普通节点,甚至只需要指定key和log两个字段就可以完成上报了。</p></li> </ol> <p style="word-break: break-all;white-space: normal;">下面是解决第一个问题(埋点代码冗长)的简单图示:</p> </section> <p style="white-space: normal;"><br></p> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100016738" data-ratio="0.29259259259259257" data-s="300,640" src="/upload/0bcaadb5750c86ecb2246c17b20a12a3.png" data-type="png" data-w="1080" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;"><span style="color: rgb(255, 102, 149);"><strong>2.2.3 解决业务入侵性</strong></span></p> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">业内流行使用插桩的方式来进行非入侵式的埋点,但切面的形式很难获取业务上下文,无法解决方法A调用方法B的trace_id透传问题,因此并不适用于这个场景。</p> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">对于trace_id透传的问题,解决方案是把trace_id缓存一下。但是需要解决以下场景的问题:</p> <ol class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;"> <li><p style="word-break: break-all;margin-bottom: 15px;">多线程并发:并行启动了多次同一个事件,且他们的完成时间也不固定,如同时上传了多张大小不一的封面。</p></li> <li><p style="word-break: break-all;margin-bottom: 15px;">事件中断:前一次事件因为某些原因中断了,永远的停留在了某个节点。</p></li> </ol> <p style="word-break: break-all;white-space: normal;">为此,我们首先引入状态机的概念,将所有节点使用有向图进行表示,这样我们便能清晰的感知到事件的发生到结束,以及某个节点后续可以流转至哪些节点、是否发生错误中断。</p> </section> <p style="white-space: normal;"><br></p> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100016737" data-ratio="0.4648148148148148" data-s="300,640" src="/upload/eabd6002ce163c9c3c421d4294a08ecc.png" data-type="png" data-w="1080" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;white-space: normal;">下面举一个具体的例子,上麦流程图和其对应的有向图:</p> </section> <p style="white-space: normal;"><br></p> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100016739" data-ratio="0.2777777777777778" data-s="300,640" src="/upload/9b501a733e8a2e81460e18e3b98fc4ae.png" data-type="png" data-w="1080" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">图中使用了虚实线来区分跨端或者跨线程的动作,其必要性可参见下文第(2)点。</p> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;"><strong>(1)自动化寻找trace_id</strong></p> <p style="word-break: break-all;white-space: normal;">当一个起始节点准备上报时:</p> </section> <section style="text-align: left;justify-content: flex-start;display: flex;flex-flow: row nowrap;margin-top: 5px;margin-bottom: 10px;"> <section style="display: inline-block;width: 100%;vertical-align: top;align-self: flex-start;flex: 0 0 auto;background-color: rgba(234, 244, 255, 0.34);padding: 25px;height: auto;"> <section style="transform: translate3d(-5px, 0px, 0px);"> <section style="text-align: justify;padding-right: 8px;padding-left: 8px;"> <ol class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;"> <li><p style="word-break: break-all;margin-bottom: 15px;">为其创建一个上报实例</p></li> <li><p style="word-break: break-all;margin-bottom: 15px;">在实例中记录trace_id、当前的节点,以及它之后可能会流转到的节点</p></li> <li><p style="word-break: break-all;">将这个实例扔到池子中</p></li> </ol> </section> </section> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;white-space: normal;">当一个非起始节点准备上报时:</p> </section> <section style="text-align: left;justify-content: flex-start;display: flex;flex-flow: row nowrap;margin-top: 5px;margin-bottom: 10px;"> <section style="display: inline-block;width: 100%;vertical-align: top;align-self: flex-start;flex: 0 0 auto;background-color: rgba(234, 244, 255, 0.34);padding: 25px;height: auto;"> <section style="transform: translate3d(-5px, 0px, 0px);"> <section style="text-align: justify;padding-right: 8px;padding-left: 8px;"> <ol class="list-paddingleft-1" style="padding-left: 40px;list-style-position: outside;"> <li><p style="word-break: break-all;margin-bottom: 15px;">组件会根据有向图去池子中查找需要流转到的节点</p></li> <li><p style="word-break: break-all;margin-bottom: 15px;">使用实例的trace_id进行上报</p></li> <li><p style="word-break: break-all;margin-bottom: 15px;">更新实例的时间戳</p></li> <li><p style="word-break: break-all;">将实例流转到下一个节点,若无后续节点,则移除实例</p></li> </ol> </section> </section> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;"><strong>(2)解决多线程问题</strong></p> <p style="word-break: break-all;white-space: normal;">这个方案似乎很完美,但从B到E是一个网络接口请求,如果先后很快地发出了两次请求,很可能会出现下面的情况:</p> </section> <p style="white-space: normal;"><br></p> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100016736" data-ratio="0.4021276595744681" data-s="300,640" src="/upload/9bd2d58a4439530dc14eb2904390787d.png" data-type="png" data-w="940" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">如果遵照上述的方案,B和E之间就会被错误的关联起来。为了规避这个问题,trace_id会在跨线程时从埋点组件中外抛,需要业务方短暂记录,并传递到下一个节点。当然,针对常用的网络请求,我们也做了易用的封装,详见2.3.1。</p> <p style="word-break: break-all;white-space: normal;">于是之前上麦的有向图会变为:</p> </section> <p style="white-space: normal;"><br></p> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100016741" data-ratio="0.4006849315068493" data-s="300,640" src="/upload/a433176788dde2006156dea387f473b1.png" data-type="png" data-w="876" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">在多线程问题解决之后,当一个含有trace_id的节点进入上报组件时,即会为其创建一个上报实例,按上文记录字段后放到池子里。</p> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">至于无trace_id的上报则完全相同,唯一的区别就是在查找节点时,加上线程id的校验,这样可以防止同一事件在不同的线程中同时启动。</p> <p style="word-break: break-all;white-space: normal;">在trace_id已经被自动化后,整体的上报流程图如下:</p> </section> <p style="white-space: normal;"><br></p> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100016743" data-ratio="0.8666666666666667" data-s="300,640" src="/upload/608100d5c23a58a46e2134ce7cb2fd28.png" data-type="png" data-w="1080" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="white-space: normal;"><br></p> <section style="color: rgb(255, 102, 149);padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;white-space: normal;"><strong>2.2.4 提升易用性后的代码架构</strong></p> </section> <p style="white-space: normal;"><br></p> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100016744" data-ratio="0.5564814814814815" data-s="300,640" src="/upload/6b11f6fd41a5838f4a2e4f800bcfcf3b.png" data-type="png" data-w="1080" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="white-space: normal;"><br></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: left;"> <section style="display: inline-block;"> <section style="width: 0.7em;height: 0.7em;margin-right: 5px;margin-top: 0.5em;display: inline-block;vertical-align: top;background-color: rgb(255, 102, 149);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> <section style="display: inline-block;vertical-align: top;text-align: center;color: rgb(12, 182, 242);"> <p><strong>2.3 继续增强鲁棒性</strong></p> </section> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;"><span style="color: rgb(255, 102, 149);"><strong>2.3.1 对“接口与广播”的封装</strong></span></p> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">在端上遇到的跨线程/跨端场景绝大多数都是网络请求和广播,因此,为了避免出错和降低复杂度,我们做了一套易用的封装:</p> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">1.&nbsp; 网络请求</p> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">(1)组件会在发起指定请求之前通过有向图自动寻路获取此次trace_id</p> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">(2)使用该trace_id上报请求事件,并会自动带上所有的业务请求参数</p> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">(3)将trace_id置于请求头,用于串联服务端节点</p> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">(4)在接口返回后,自动上报响应数据,若接口错误,会将该节点标记为error</p> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">2.&nbsp; 广播</p> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">(1)组件会在指定广播到达时,尝试去获取trace_id字段。</p> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">(2)若获取成功,则自动进行上报,若没有,则会走自动化上报流程。</p> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">这样,业务方即使遇到跨线程/跨端,也无需关心trace_id了,在这两种场景下彻底做到了业务无感。</p> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;"><br></p> <p style="margin-bottom: 15px;white-space: normal;"><span style="color: rgb(255, 102, 149);"><strong>2.3.2 对“抗风险能力”的补足</strong></span></p> <p style="margin-bottom: 15px;white-space: normal;">当业务链路与对应的有向图不符时,trace_id的自动化管理便会失效。为此我们设计了特殊异常case的监控:</p> <p style="margin-bottom: 15px;white-space: normal;">1.&nbsp; 事件跟踪上下文丢失</p> <p style="margin-bottom: 15px;white-space: normal;">自动化寻找trace_id失败,此种情况多发生在上报的埋点与有向图描述不符,此时埋点组件会上报一个警告埋点触达开发及时修改链路。</p> <p style="margin-bottom: 15px;white-space: normal;">2.&nbsp; 事件跟踪超时</p> <p style="white-space: normal;">即上次单线程的流转还未结束,新的节点就已到达。此种情况多发生在流转过程被意外打断,如check失败后直接return。此时原事件在看板中会表现为链路中断的错误。同样的,会上报一个警告埋点。</p> </section> <p style="white-space: normal;"><br></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: left;"> <section style="display: inline-block;"> <section style="width: 0.7em;height: 0.7em;margin-right: 5px;margin-top: 0.5em;display: inline-block;vertical-align: top;background-color: rgb(255, 102, 149);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> <section style="display: inline-block;vertical-align: top;text-align: center;color: rgb(12, 182, 242);"> <p><strong>2.4 上报组件整体概览</strong></p> </section> </section> </section> <p style="white-space: normal;"><br></p> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100016745" data-ratio="1.0740740740740742" data-s="300,640" src="/upload/80b148114e57afec3342be1ea13f72fe.png" data-type="png" data-w="1080" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="white-space: normal;"><br></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: left;"> <section style="display: inline-block;"> <section style="width: 0.7em;height: 0.7em;margin-right: 5px;margin-top: 0.5em;display: inline-block;vertical-align: top;background-color: rgb(255, 102, 149);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> <section style="display: inline-block;vertical-align: top;text-align: center;font-size: 18px;color: rgb(12, 182, 242);"> <p><strong>3. 数据处理和存储</strong></p> </section> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;white-space: normal;">在处理上报的海量数据时,需要清洗掉错误的数据,并解析各个终端上报的不同数据结构,转化为统一数据模型。由于数据是逐条上报的,必须将这些离散数据串联成完整的事件链路,这样就知道用户操作了什么、经历了哪些端、哪些节点出了问题或漏了哪些节点。</p> </section> <p style="white-space: normal;"><br></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: left;"> <section style="display: inline-block;"> <section style="width: 0.7em;height: 0.7em;margin-right: 5px;margin-top: 0.5em;display: inline-block;vertical-align: top;background-color: rgb(255, 102, 149);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> <section style="display: inline-block;vertical-align: top;text-align: center;color: rgb(12, 182, 242);"> <p><strong>3.1 事件串联</strong></p> </section> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;white-space: normal;">(1)单trace_id串联:事件由唯一的trace_id串联整个流程。</p> </section> <p style="white-space: normal;"><br></p> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100016742" data-ratio="0.17685185185185184" data-s="300,640" src="/upload/cfda7463e97209578cef140798ab9625.png" data-type="png" data-w="1080" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">(2)多trace_id串联:事件由多端各自的trace_id组合而成。</p> <p style="word-break: break-all;white-space: normal;">为兼容业务服务和广播服务各自独立的trace追踪系统,我们实现了一套多重映射算法,且无缝兼容了单trace_id方案,最终溯源成事件开始的原始trace_id。</p> </section> <p style="white-space: normal;"><br></p> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100016747" data-ratio="0.2611111111111111" data-s="300,640" src="/upload/c8015cbfd144097d99432c1ac0c28660.png" data-type="png" data-w="1080" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="white-space: normal;"><br></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: left;"> <section style="display: inline-block;"> <section style="width: 0.7em;height: 0.7em;margin-right: 5px;margin-top: 0.5em;display: inline-block;vertical-align: top;background-color: rgb(255, 102, 149);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> <section style="display: inline-block;vertical-align: top;text-align: center;color: rgb(12, 182, 242);"> <p><strong>3.2 数据清洗与存储</strong></p> </section> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;white-space: normal;">为应对直播的实时性要求,我们采用流计算技术。先快速筛选出trace相关事件,再清洗掉异常数据,在单次流计算执行过程中进行映射建立关系并落表存储,实现小于5min级别的数据响应处理。数据表支持灵活的定制化查询和分析需求。</p> </section> <p style="white-space: normal;"><br></p> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100016749" data-ratio="0.4166666666666667" data-s="300,640" src="/upload/40a5f936316402b108ebea713654b58e.png" data-type="png" data-w="1080" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="white-space: normal;"><br></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: left;"> <section style="display: inline-block;"> <section style="width: 0.7em;height: 0.7em;margin-right: 5px;margin-top: 0.5em;display: inline-block;vertical-align: top;background-color: rgb(255, 102, 149);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> <section style="display: inline-block;vertical-align: top;text-align: center;font-size: 18px;color: rgb(12, 182, 242);"> <p><strong>4. 数据可视化</strong></p> </section> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;white-space: normal;">可视化简化了查询过程,能快速准确地捕捉异常和关键信息。适用于开发、测试、产品、运营、客服等角色。</p> </section> <p style="white-space: normal;"><br></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: left;"> <section style="display: inline-block;"> <section style="width: 0.7em;height: 0.7em;margin-right: 5px;margin-top: 0.5em;display: inline-block;vertical-align: top;background-color: rgb(255, 102, 149);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> <section style="display: inline-block;vertical-align: top;text-align: center;font-size: 18px;color: rgb(12, 182, 242);"> <p><strong>4.1 覆盖场景</strong></p> </section> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;white-space: normal;">从App启动到退出,从开播到关播,从上麦到下麦,从PK发起到结束等关键业务场景。</p> </section> <p style="white-space: normal;"><br></p> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100016748" data-ratio="0.4101851851851852" data-s="300,640" src="/upload/4273b812792433737edde605ed63a130.jpg" data-type="jpeg" data-w="1080" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="white-space: normal;"><br></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: left;"> <section style="display: inline-block;"> <section style="width: 0.7em;height: 0.7em;margin-right: 5px;margin-top: 0.5em;display: inline-block;vertical-align: top;background-color: rgb(255, 102, 149);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> <section style="display: inline-block;vertical-align: top;text-align: center;color: rgb(12, 182, 242);"> <p><strong>4.2 落地效果</strong></p> </section> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;white-space: normal;">在日常业务中,已经有效解决了很多实际问题,以下是遇到的一些案例查询:</p> </section> <p style="white-space: normal;"><br></p> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100016750" data-ratio="0.4888888888888889" data-s="300,640" src="/upload/26e6ea8f0d9ada1c88c3a7a0d6c1ce41.png" data-type="png" data-w="1080" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="white-space: normal;"><br></p> <section style="margin-top: 10px;margin-bottom: 10px;text-align: center;"> <section style="display: inline-block;vertical-align: top;padding-left: 10px;"> <section style="border-bottom: 1px dashed rgb(0, 0, 0);padding-left: 5px;font-size: 20px;color: rgb(12, 182, 242);"> <p><strong>三、结束语</strong></p> </section> <section style="margin-top: -7px;margin-left: -10px;width: 10px;"> <section style="transform: rotate(0deg);margin-left: auto;width: 7px;height: 7px;background-color: rgb(255, 102, 149);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> <section style="margin-top: -4px;margin-left: -3px;width: 10px;height: 10px;background-color: rgb(12, 182, 242);"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> <p style="white-space: normal;"><br></p> <section style="padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">不知何时起,“用关键链路查一下”已经成了身边同事常说的口头禅,整套排障体系的价值,也得到了验证。</p> <p style="word-break: break-all;margin-bottom: 15px;white-space: normal;">未来还有许多要做的事,我们将致力于拓展业务覆盖面、建立业务健康度监控体系、提升上下文信息的有效性等。</p> <p style="word-break: break-all;white-space: normal;">我们相信,通过不断的技术创新和服务优化,我们的业务能够迎接更大的挑战,为用户创造更大的价值。</p> </section> <p style="white-space: normal;"><br></p> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100016751" data-ratio="0.562962962962963" data-s="300,640" src="/upload/1779f6c082aca73391a66d5626706c69.png" data-type="png" data-w="1080" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="white-space: normal;"><br></p> <section style="text-align: center;font-size: 12px;color: rgb(160, 160, 160);padding-right: 8px;padding-left: 8px;"> <p style="word-break: break-all;margin-bottom: 15px;">-End-</p> <p style="word-break: break-all;">作者丨瞳舞舞、小猪、钱来、星空凛、lish、志超</p> </section> <p style="white-space: normal;"><br></p> <section class="mp_profile_iframe_wrp"> <mp-common-profile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-id="MzU4MjQ0MTU4Ng==" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/z9BgVMEm7YtTw2oONBkwaiaM9hBxUj6yRLDEw8rSSxR8wWZFLjjXWpmGq5LNDlEAn4v9lSALDiaGfC4MyPZwL95g/0?wx_fmt=png" data-nickname="k8s技术圈" data-alias="kube100" data-signature="专注容器、专注 kubernetes 技术......" data-from="0" data-is_biz_ban="0"></mp-common-profile> </section> </section> <p style="display: none;margin-bottom: 24px;"> <mp-style-type data-value="3"></mp-style-type></p>

Apache Amoro(阿莫罗)是个啥玩意儿?听过没?

作者:微信小助手

<p style="text-align: center;"><strong><span style="font-size: 17px;letter-spacing: 0.578px;text-decoration: none;">Lakehouse 管理系统</span></strong></p> <p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100001187" data-ratio="0.2962962962962963" data-s="300,640" src="/upload/b28ae124a53c66e2ce85a9b853867ec7.png" data-type="png" data-w="1080" style=""></p> <p><strong><span style="font-size: 16px;">一、架构图</span></strong></p> <p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100001189" data-ratio="0.5416666666666666" data-s="300,640" src="/upload/5301f8ccae3dc796b9f98d104467eaf0.png" data-type="png" data-w="1080" style=""></p> <p style="text-align: center;"><span style="letter-spacing: 0.578px;text-decoration: none;font-size: 16px;">Amoro 为用户、平台和产品构建湖原生数据仓库和架构</span></p> <p><strong><span style="font-size: 16px;">二、主要特点</span></strong><br></p> <p><strong><span style="font-size: 16px;">1、<span style="letter-spacing: 0.578px;text-decoration: none;">自我优化</span></span></strong><span style="font-size: 16px;letter-spacing: 0.578px;text-decoration: none;"></span></p> <p><span style="letter-spacing: 0.578px;text-decoration: none solid rgba(0, 0, 0, 0.9);font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;持续优化表,包括压缩小文件,变更文件,定期删除过期文件,以保持较高的查询性能并降低存储成本。</span></p> <p><strong><span style="letter-spacing: 0.578px;text-decoration: none solid rgba(0, 0, 0, 0.9);font-size: 16px;">2、目录服务</span></strong><span style="letter-spacing: 0.578px;text-decoration: none solid rgba(0, 0, 0, 0.9);font-size: 16px;"></span></p> <p><span style="color: rgb(0, 0, 0);font-size: 16px;"><span style="color: rgb(0, 0, 0);letter-spacing: 0.578px;text-decoration: none solid rgba(0, 0, 0, 0.9);">&nbsp;&nbsp;</span><span style="letter-spacing: 0.578px;text-decoration: none;color: rgb(0, 0, 0);">&nbsp;&nbsp;<span style="text-decoration: none;color: rgb(83, 87, 106);font-family: Lato, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;letter-spacing: normal;text-align: start;text-wrap: wrap;background-color: rgb(255, 255, 255);">为所有计算引擎提供统一的目录服务,并可与现有的元数据存储服务(如Hive Metastore、AWS Glue)一起使用。</span></span></span></p> <p><strong><span style="font-size: 16px;">3、<span style="letter-spacing: 0.578px;text-decoration: none;">管理工具</span></span></strong><span style="font-size: 16px;letter-spacing: 0.578px;text-decoration: none;"></span></p> <p><span style="font-size: 16px;"><span style="text-decoration: none;color: rgb(83, 87, 106);font-family: Lato, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;letter-spacing: normal;text-align: start;text-wrap: wrap;background-color: rgb(255, 255, 255);">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-family: Lato, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;text-align: start;text-wrap: wrap;background-color: rgb(255, 255, 255);letter-spacing: 0.578px;text-decoration: none;color: rgb(0, 0, 0);">提供多种管理工具,包括WEB UI和标准SQL命令行,帮助您更快上手并更轻松地与其他系统集成。</span></span></p> <p><strong><span style="font-size: 16px;">4、<span style="letter-spacing: 0.578px;text-decoration: none;">多种格式</span></span></strong><span style="font-size: 16px;letter-spacing: 0.578px;text-decoration: none;"></span></p> <p><span style="letter-spacing: 0.578px;text-decoration: none;font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;支持Iceberg、Paimon、Mixed-Iceberg、Mixed-Hive等不同的表格式,满足不同的场景需求,并提供统一的管理能力。</span></p> <p><strong><span style="font-size: 16px;">5、<span style="letter-spacing: 0.578px;text-decoration: none;">丰富的插件</span></span></strong><span style="font-size: 16px;letter-spacing: 0.578px;text-decoration: none;"></span></p> <p><span style="letter-spacing: 0.578px;text-decoration: none;font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;提供各种插件以便与其他系统集成,例如使用 Flink 进行持续优化以及使用 Spark 和 Kyuubi 进行数据分析。</span></p> <p><strong><span style="font-size: 16px;">6、<span style="letter-spacing: 0.578px;text-decoration: none;">独立于基础设施</span></span></strong></p> <p><span style="letter-spacing: 0.578px;text-decoration: none;font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;可在私有环境、云环境、混合云环境、多云环境中轻松部署和使用。</span></p> <p><strong><span style="letter-spacing: 0.578px;text-decoration: none;font-size: 16px;">7、支持多处理引擎</span></strong><span style="letter-spacing: 0.578px;text-decoration: none;font-size: 16px;"></span></p> <p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100001203" data-ratio="0.3658256880733945" data-s="300,640" src="/upload/c24ac9315cf9c29f0d18926c8bb4303f.png" data-type="png" data-w="872" style=""></p> <p><strong><span style="font-size: 16px;">三、快速入门</span></strong><br></p> <p><span style="letter-spacing: 0.578px;text-decoration: none;font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;快速体验其核心功能。您可以选择使用或Iceberg Format来Mixed-Iceberg Format完成整个过程。</span><span style="color: rgb(36, 41, 47);font-family: sans-serif, -apple-system, BlinkMacSystemFont, &quot;segoe ui&quot;, Helvetica, Arial, &quot;apple color emoji&quot;, &quot;segoe ui emoji&quot;;font-size: 16px;letter-spacing: normal;text-align: start;vertical-align: inherit;">在开始快速演示之前,需要执行一些步骤来准备环境。最快的入门方法是使用使用 apache/amoro 映像的 docker-compose 文件。要使用它,您需要安装 Docker </span><span style="vertical-align: inherit;">CLI</span><span style="color: rgb(36, 41, 47);font-family: sans-serif, -apple-system, BlinkMacSystemFont, &quot;segoe ui&quot;, Helvetica, Arial, &quot;apple color emoji&quot;, &quot;segoe ui emoji&quot;;font-size: 16px;letter-spacing: normal;text-align: start;vertical-align: inherit;">以及</span><span style="vertical-align: inherit;">Docker Compose CLI</span><span style="color: rgb(36, 41, 47);font-family: sans-serif, -apple-system, BlinkMacSystemFont, &quot;segoe ui&quot;, Helvetica, Arial, &quot;apple color emoji&quot;, &quot;segoe ui emoji&quot;;font-size: 16px;letter-spacing: normal;text-align: start;vertical-align: inherit;">。</span></p> <p style="margin-bottom: 16px;color: rgb(36, 41, 47);font-family: sans-serif, -apple-system, BlinkMacSystemFont, &quot;segoe ui&quot;, Helvetica, Arial, &quot;apple color emoji&quot;, &quot;segoe ui emoji&quot;;font-size: 16px;letter-spacing: normal;text-align: start;text-wrap: wrap;background-color: rgb(255, 255, 255);"><span style="vertical-align: inherit;font-size: 16px;">拥有这些之后,将下面的 yaml 保存到名为 docker-compose.yml 的文件中:</span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="properties"><code><span class="code-snippet_outer">version: "3"</span></code><code><span class="code-snippet_outer">services:</span></code><code><span class="code-snippet_outer"> minio:</span></code><code><span class="code-snippet_outer"> image: minio/minio</span></code><code><span class="code-snippet_outer"> container_name: minio</span></code><code><span class="code-snippet_outer"> environment:</span></code><code><span class="code-snippet_outer"> - MINIO_ROOT_USER=admin</span></code><code><span class="code-snippet_outer"> - MINIO_ROOT_PASSWORD=password</span></code><code><span class="code-snippet_outer"> - MINIO_DOMAIN=minio</span></code><code><span class="code-snippet_outer"> networks:</span></code><code><span class="code-snippet_outer"> amoro_network:</span></code><code><span class="code-snippet_outer"> aliases:</span></code><code><span class="code-snippet_outer"> - warehouse.minio</span></code><code><span class="code-snippet_outer"> ports:</span></code><code><span class="code-snippet_outer"> - 9001:9001</span></code><code><span class="code-snippet_outer"> - 9000:9000</span></code><code><span class="code-snippet_outer"> command: [ "server", "/data", "--console-address", ":9001" ]</span></code><code><span class="code-snippet_outer"> mc:</span></code><code><span class="code-snippet_outer"> depends_on:</span></code><code><span class="code-snippet_outer"> - minio</span></code><code><span class="code-snippet_outer"> image: minio/mc</span></code><code><span class="code-snippet_outer"> container_name: mc</span></code><code><span class="code-snippet_outer"> networks:</span></code><code><span class="code-snippet_outer"> amoro_network:</span></code><code><span class="code-snippet_outer"> environment:</span></code><code><span class="code-snippet_outer"> - AWS_ACCESS_KEY_ID=admin</span></code><code><span class="code-snippet_outer"> - AWS_SECRET_ACCESS_KEY=password</span></code><code><span class="code-snippet_outer"> - AWS_REGION=us-east-1</span></code><code><span class="code-snippet_outer"> entrypoint: &gt;</span></code><code><span class="code-snippet_outer"> /bin/sh -c "</span></code><code><span class="code-snippet_outer"> until (/usr/bin/mc config host add minio http://minio:9000 admin password) do echo '...waiting...' &amp;&amp; sleep 1; done;</span></code><code><span class="code-snippet_outer"> /usr/bin/mc rm -r --force minio/warehouse;</span></code><code><span class="code-snippet_outer"> /usr/bin/mc mb minio/warehouse;</span></code><code><span class="code-snippet_outer"> /usr/bin/mc policy set public minio/warehouse;</span></code><code><span class="code-snippet_outer"> tail -f /dev/null</span></code><code><span class="code-snippet_outer"> " </span></code><code><span class="code-snippet_outer"> amoro:</span></code><code><span class="code-snippet_outer"> image: apache/amoro</span></code><code><span class="code-snippet_outer"> container_name: amoro</span></code><code><span class="code-snippet_outer"> ports:</span></code><code><span class="code-snippet_outer"> - 8081:8081</span></code><code><span class="code-snippet_outer"> - 1630:1630</span></code><code><span class="code-snippet_outer"> - 1260:1260</span></code><code><span class="code-snippet_outer"> environment:</span></code><code><span class="code-snippet_outer"> - JVM_XMS=1024</span></code><code><span class="code-snippet_outer"> networks:</span></code><code><span class="code-snippet_outer"> amoro_network:</span></code><code><span class="code-snippet_outer"> aliases:</span></code><code><span class="code-snippet_outer"> - warehouse.minio</span></code><code><span class="code-snippet_outer"> volumes:</span></code><code><span class="code-snippet_outer"> - ./amoro:/tmp/warehouse</span></code><code><span class="code-snippet_outer"> command: ["/entrypoint.sh", "ams"]</span></code><code><span class="code-snippet_outer"> tty: true</span></code><code><span class="code-snippet_outer"> stdin_open: true</span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer">networks:</span></code><code><span class="code-snippet_outer"> amoro_network:</span></code><code><span class="code-snippet_outer"> driver: bridge</span></code></pre> </section> <p><span style="letter-spacing: 0.578px;text-decoration: none;font-size: 16px;">接下来,使用以下命令启动 docker 容器:</span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js"><code><span class="code-snippet_outer">docker-compose up</span></code></pre> </section> <p><strong style="font-size: var(--articleFontsize);letter-spacing: 0.034em;"><span style="font-size: 16px;letter-spacing: 0.578px;">3.1、准备步骤</span></strong></p> <h3 style="font-family: Lato, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;font-weight: 600;line-height: 1.25;color: rgb(36, 41, 47);margin-top: 24px;margin-bottom: 16px;font-size: 1.25em;letter-spacing: normal;text-align: start;text-wrap: wrap;background-color: rgb(255, 255, 255);"><span style="vertical-align: inherit;font-size: 16px;">3.1.1、创建优化器</span></h3> <p style="margin-bottom: 16px;color: rgb(36, 41, 47);font-family: sans-serif, -apple-system, BlinkMacSystemFont, &quot;segoe ui&quot;, Helvetica, Arial, &quot;apple color emoji&quot;, &quot;segoe ui emoji&quot;;font-size: 16px;letter-spacing: normal;text-align: start;text-wrap: wrap;background-color: rgb(255, 255, 255);"><span style="vertical-align: inherit;font-size: 16px;">在浏览器中打开</span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="javascript"><code><span class="code-snippet_outer">http:<span class="code-snippet__comment">//localhost:1630</span></span></code></pre> </section> <p style="margin-bottom: 16px;color: rgb(36, 41, 47);font-family: sans-serif, -apple-system, BlinkMacSystemFont, &quot;segoe ui&quot;, Helvetica, Arial, &quot;apple color emoji&quot;, &quot;segoe ui emoji&quot;;font-size: 16px;letter-spacing: normal;text-align: start;text-wrap: wrap;background-color: rgb(255, 255, 255);">用户名/密码:<span style="color: rgb(199, 37, 78);font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace;font-size: 16px;letter-spacing: normal;text-align: start;text-wrap: wrap;background-color: rgb(255, 255, 255);">admin/admin</span>&nbsp;,输入即可登录仪表盘。<br></p> <p style="margin-bottom: 16px;color: rgb(36, 41, 47);font-family: sans-serif, -apple-system, BlinkMacSystemFont, &quot;segoe ui&quot;, Helvetica, Arial, &quot;apple color emoji&quot;, &quot;segoe ui emoji&quot;;font-size: 16px;letter-spacing: normal;text-align: start;text-wrap: wrap;background-color: rgb(255, 255, 255);"><span style="vertical-align: inherit;font-size: 16px;">点击</span><code style="font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace;font-size: 13.6px;padding: 0.2em 0.4em;color: rgb(199, 37, 78);background-color: var(--color-neutral-muted);border-radius: 6px;"><span style="font-size: 16px;">Optimizing</span></code><span style="vertical-align: inherit;font-size: 16px;">侧边栏的 ,选择</span><code style="font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace;font-size: 13.6px;padding: 0.2em 0.4em;color: rgb(199, 37, 78);background-color: var(--color-neutral-muted);border-radius: 6px;"><span style="font-size: 16px;">Optimizer Groups</span></code><span style="vertical-align: inherit;font-size: 16px;">并点击</span><code style="font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace;font-size: 13.6px;padding: 0.2em 0.4em;color: rgb(199, 37, 78);background-color: var(--color-neutral-muted);border-radius: 6px;"><span style="font-size: 16px;">Add Group</span></code><span style="vertical-align: inherit;font-size: 16px;">按钮在创建目录之前创建一个新组:</span></p> <p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100001190" data-ratio="0.32251908396946566" data-s="300,640" src="/upload/80ca0b51403900fd3d08e682eb0c8226.png" data-type="png" data-w="1048" style=""></p> <h3 style="margin-top: 24px;margin-bottom: 16px;font-weight: 600;font-size: 1.25em;text-wrap: wrap;font-family: Lato, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;line-height: 1.25;color: rgb(36, 41, 47);letter-spacing: normal;text-align: start;background-color: rgb(255, 255, 255);"><span style="vertical-align: inherit;font-size: 16px;">3.1.2、<span style="color: rgb(36, 41, 47);font-size: 16px;letter-spacing: normal;text-wrap: wrap;">创建目</span><span style="color: rgb(36, 41, 47);font-size: 16px;letter-spacing: normal;text-wrap: wrap;">录</span></span></h3> <p><span style="vertical-align: inherit;font-size: 16px;"><span style="color: rgb(36, 41, 47);font-size: 16px;letter-spacing: normal;text-wrap: wrap;"><span style="color: rgb(36, 41, 47);font-size: 16px;letter-spacing: normal;text-decoration: none solid rgb(36, 41, 47);">点击Catalogs侧边栏的 ,点击+Catalog List下的按钮,创建一个测试目录,并将其命名为demo_catalog:</span></span></span></p> <p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100001191" data-ratio="0.4876660341555977" data-s="300,640" src="/upload/12afb63838d99690cf4ea5a5630ce7f3.png" data-type="png" data-w="1054" style=""></p> <h3 style="margin-top: 24px;margin-bottom: 16px;font-weight: 600;font-size: 1.25em;color: rgb(36, 41, 47);letter-spacing: normal;text-wrap: wrap;font-family: Lato, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;line-height: 1.25;text-align: start;background-color: rgb(255, 255, 255);"><span style="font-size: 16px;"><span style="font-size: 16px;vertical-align: inherit;">3.1.3、</span>启动优化</span></h3> <h3 style="margin-top: 24px;margin-bottom: 16px;font-weight: 600;font-size: 1.25em;color: rgb(36, 41, 47);letter-spacing: normal;text-wrap: wrap;font-family: Lato, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;line-height: 1.25;text-align: start;background-color: rgb(255, 255, 255);"><span style="vertical-align: inherit;font-size: 16px;"></span></h3> <section style="line-height: 1.6em;text-align: justify;margin: 0px 0px 24px;text-indent: 0em;"> <span style="letter-spacing: 0.578px;text-decoration: none solid rgba(0, 0, 0, 0.9);font-size: 16px;">&nbsp;&nbsp;&nbsp;&nbsp;点击Optimizing侧边栏的 ,选择Optimizer Group标签,点击scale-out群组 的操作local。</span> </section> <p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100001192" data-ratio="0.2881679389312977" data-s="300,640" src="/upload/01b9f8b82494d0a61034daf0db3c2f2e.png" data-type="png" data-w="1048" style=""></p> <p style="margin-bottom: 16px;color: rgb(36, 41, 47);font-family: sans-serif, -apple-system, BlinkMacSystemFont, &quot;segoe ui&quot;, Helvetica, Arial, &quot;apple color emoji&quot;, &quot;segoe ui emoji&quot;;font-size: 16px;letter-spacing: normal;text-align: start;text-wrap: wrap;background-color: rgb(255, 255, 255);"><span style="vertical-align: inherit;">将优化器的并发度设置为1,然后单击</span><code style="font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace;font-size: 13.6px;padding: 0.2em 0.4em;color: rgb(199, 37, 78);background-color: var(--color-neutral-muted);border-radius: 6px;">OK</code><span style="vertical-align: inherit;">。</span></p> <p style="margin-bottom: 16px;color: rgb(36, 41, 47);font-family: sans-serif, -apple-system, BlinkMacSystemFont, &quot;segoe ui&quot;, Helvetica, Arial, &quot;apple color emoji&quot;, &quot;segoe ui emoji&quot;;font-size: 16px;letter-spacing: normal;text-align: start;text-wrap: wrap;background-color: rgb(255, 255, 255);"><span style="vertical-align: inherit;">然后你可以切换到标签页</span><code style="font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace;font-size: 13.6px;padding: 0.2em 0.4em;color: rgb(199, 37, 78);background-color: var(--color-neutral-muted);border-radius: 6px;">Optimizers</code><span style="vertical-align: inherit;">,你可以在这里找到新启动的优化器。</span></p> <p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100001193" data-ratio="0.35727969348659006" data-s="300,640" src="/upload/d1781db34eb15fd4891933bf67962c8f.png" data-type="png" data-w="1044" style=""></p> <p><strong><span style="font-size: 16px;"><span style="font-size: 16px;letter-spacing: 0.578px;text-decoration: none;">3.2、</span><span style="font-size: 16px;background-color: rgb(255, 255, 255);color: rgb(36, 41, 47);font-family: Lato, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;font-weight: 600;letter-spacing: normal;text-align: start;">演示</span></span></strong></p> <p><strong><span style="font-size: 16px;"><span style="font-size: 16px;letter-spacing: 0.578px;text-decoration: none;">3.2.1、</span><span style="font-size: 16px;letter-spacing: 0.578px;">初始化</span></span></strong><span style="font-size: 16px;"><span style="font-size: 16px;letter-spacing: 0.578px;"></span></span></p> <p><span style="color: rgb(36, 41, 47);font-family: sans-serif, -apple-system, BlinkMacSystemFont, &quot;segoe ui&quot;, Helvetica, Arial, &quot;apple color emoji&quot;, &quot;segoe ui emoji&quot;;font-size: 16px;letter-spacing: normal;text-align: start;text-wrap: wrap;background-color: rgb(255, 255, 255);vertical-align: inherit;"><span style="vertical-align: inherit;">点击</span></span><code style="font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace;font-size: 13.6px;padding: 0.2em 0.4em;color: rgb(199, 37, 78);border-radius: 6px;letter-spacing: normal;text-align: start;text-wrap: wrap;">Terminal</code><span style="color: rgb(36, 41, 47);font-family: sans-serif, -apple-system, BlinkMacSystemFont, &quot;segoe ui&quot;, Helvetica, Arial, &quot;apple color emoji&quot;, &quot;segoe ui emoji&quot;;font-size: 16px;letter-spacing: normal;text-align: start;text-wrap: wrap;background-color: rgb(255, 255, 255);vertical-align: inherit;"><span style="vertical-align: inherit;">侧边栏的 ,你可以在这里使用 SQL 创建测试表。终端目前支持执行 Spark SQL 语句。</span></span></p> <p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100001194" data-ratio="0.36657169990503324" data-s="300,640" src="/upload/1f3f8e352cb2f20e4ca28062824cb3d1.png" data-type="png" data-w="1053" style=""></p> <p><span style="color: rgb(36, 41, 47);font-family: sans-serif, -apple-system, BlinkMacSystemFont, &quot;segoe ui&quot;, Helvetica, Arial, &quot;apple color emoji&quot;, &quot;segoe ui emoji&quot;;font-size: 16px;letter-spacing: normal;text-align: start;text-wrap: wrap;background-color: rgb(255, 255, 255);vertical-align: inherit;"><span style="vertical-align: inherit;">点击</span></span><code style="font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace;font-size: 13.6px;padding: 0.2em 0.4em;color: rgb(199, 37, 78);border-radius: 6px;letter-spacing: normal;text-align: start;text-wrap: wrap;">RUN</code><span style="color: rgb(36, 41, 47);font-family: sans-serif, -apple-system, BlinkMacSystemFont, &quot;segoe ui&quot;, Helvetica, Arial, &quot;apple color emoji&quot;, &quot;segoe ui emoji&quot;;font-size: 16px;letter-spacing: normal;text-align: start;text-wrap: wrap;background-color: rgb(255, 255, 255);vertical-align: inherit;"><span style="vertical-align: inherit;">SQL编辑器上方的按钮,等待SQL查询执行完毕,即可在SQL编辑器下看到查询结果。</span></span></p> <p><strong><span style="color: rgb(36, 41, 47);font-size: 16px;letter-spacing: normal;text-decoration: none solid rgb(36, 41, 47);"><span style="font-size: 16px;"><span style="letter-spacing: 0.578px;">3.2.2、</span></span>改变数据</span></strong></p> <p><span style="color: rgb(36, 41, 47);font-family: sans-serif, -apple-system, BlinkMacSystemFont, &quot;segoe ui&quot;, Helvetica, Arial, &quot;apple color emoji&quot;, &quot;segoe ui emoji&quot;;font-size: 16px;letter-spacing: normal;text-align: start;text-wrap: wrap;background-color: rgb(255, 255, 255);vertical-align: inherit;"><span style="vertical-align: inherit;">在中逐个执行以下 SQL 语句</span></span><code style="font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace;font-size: 13.6px;padding: 0.2em 0.4em;color: rgb(199, 37, 78);border-radius: 6px;letter-spacing: normal;text-align: start;text-wrap: wrap;">Terminal</code><span style="color: rgb(36, 41, 47);font-family: sans-serif, -apple-system, BlinkMacSystemFont, &quot;segoe ui&quot;, Helvetica, Arial, &quot;apple color emoji&quot;, &quot;segoe ui emoji&quot;;font-size: 16px;letter-spacing: normal;text-align: start;text-wrap: wrap;background-color: rgb(255, 255, 255);vertical-align: inherit;"><span style="vertical-align: inherit;">:</span></span><span style="color: rgb(36, 41, 47);font-family: sans-serif, -apple-system, BlinkMacSystemFont, &quot;segoe ui&quot;, Helvetica, Arial, &quot;apple color emoji&quot;, &quot;segoe ui emoji&quot;;font-size: 16px;letter-spacing: normal;text-align: start;text-wrap: wrap;background-color: rgb(255, 255, 255);vertical-align: inherit;"></span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="sql"><code><span class="code-snippet_outer"><span class="code-snippet__comment">-- insert a few rows first</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">INSERT</span> <span class="code-snippet__keyword">INTO</span> db.user (<span class="code-snippet__keyword">id</span>, <span class="code-snippet__keyword">name</span>, ts) <span class="code-snippet__keyword">VALUES</span> (<span class="code-snippet__number">4</span>, <span class="code-snippet__string">'rock'</span>, <span class="code-snippet__keyword">CAST</span>(<span class="code-snippet__string">'2022-07-02 01:11:20'</span> <span class="code-snippet__keyword">AS</span> <span class="code-snippet__built_in">TIMESTAMP</span>));</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">INSERT</span> <span class="code-snippet__keyword">INTO</span> db.user (<span class="code-snippet__keyword">id</span>, <span class="code-snippet__keyword">name</span>, ts) <span class="code-snippet__keyword">VALUES</span> (<span class="code-snippet__number">5</span>, <span class="code-snippet__string">'jack'</span>, <span class="code-snippet__keyword">CAST</span>(<span class="code-snippet__string">'2022-07-02 05:22:10'</span> <span class="code-snippet__keyword">AS</span> <span class="code-snippet__built_in">TIMESTAMP</span>));</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">INSERT</span> <span class="code-snippet__keyword">INTO</span> db.user (<span class="code-snippet__keyword">id</span>, <span class="code-snippet__keyword">name</span>, ts) <span class="code-snippet__keyword">VALUES</span> (<span class="code-snippet__number">6</span>, <span class="code-snippet__string">'mars'</span>, <span class="code-snippet__keyword">CAST</span>(<span class="code-snippet__string">'2022-07-02 08:23:20'</span> <span class="code-snippet__keyword">AS</span> <span class="code-snippet__built_in">TIMESTAMP</span>));</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">INSERT</span> <span class="code-snippet__keyword">INTO</span> db.user (<span class="code-snippet__keyword">id</span>, <span class="code-snippet__keyword">name</span>, ts) <span class="code-snippet__keyword">VALUES</span> (<span class="code-snippet__number">7</span>, <span class="code-snippet__string">'cloe'</span>, <span class="code-snippet__keyword">CAST</span>(<span class="code-snippet__string">'2022-07-02 08:44:50'</span> <span class="code-snippet__keyword">AS</span> <span class="code-snippet__built_in">TIMESTAMP</span>));</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">INSERT</span> <span class="code-snippet__keyword">INTO</span> db.user (<span class="code-snippet__keyword">id</span>, <span class="code-snippet__keyword">name</span>, ts) <span class="code-snippet__keyword">VALUES</span> (<span class="code-snippet__number">8</span>, <span class="code-snippet__string">'smith'</span>, <span class="code-snippet__keyword">CAST</span>(<span class="code-snippet__string">'2022-07-02 10:52:20'</span> <span class="code-snippet__keyword">AS</span> <span class="code-snippet__built_in">TIMESTAMP</span>));</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">INSERT</span> <span class="code-snippet__keyword">INTO</span> db.user (<span class="code-snippet__keyword">id</span>, <span class="code-snippet__keyword">name</span>, ts) <span class="code-snippet__keyword">VALUES</span> (<span class="code-snippet__number">9</span>, <span class="code-snippet__string">'piec'</span>, <span class="code-snippet__keyword">CAST</span>(<span class="code-snippet__string">'2022-07-02 11:24:30'</span> <span class="code-snippet__keyword">AS</span> <span class="code-snippet__built_in">TIMESTAMP</span>));</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">INSERT</span> <span class="code-snippet__keyword">INTO</span> db.user (<span class="code-snippet__keyword">id</span>, <span class="code-snippet__keyword">name</span>, ts) <span class="code-snippet__keyword">VALUES</span> (<span class="code-snippet__number">10</span>, <span class="code-snippet__string">'vovo'</span>, <span class="code-snippet__keyword">CAST</span>(<span class="code-snippet__string">'2022-07-02 12:00:20'</span> <span class="code-snippet__keyword">AS</span> <span class="code-snippet__built_in">TIMESTAMP</span>));</span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">-- delete some rows then</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">DELETE</span> <span class="code-snippet__keyword">FROM</span> db.user <span class="code-snippet__keyword">where</span> <span class="code-snippet__keyword">id</span> = <span class="code-snippet__number">1</span>;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">DELETE</span> <span class="code-snippet__keyword">FROM</span> db.user <span class="code-snippet__keyword">where</span> <span class="code-snippet__keyword">id</span> = <span class="code-snippet__number">4</span>;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">DELETE</span>&nbsp;<span class="code-snippet__keyword">FROM</span>&nbsp;db.user&nbsp;<span class="code-snippet__keyword">where</span>&nbsp;<span class="code-snippet__keyword">id</span>&nbsp;=&nbsp;<span class="code-snippet__number">7</span>;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">-- query the table </span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">SELECT</span> * <span class="code-snippet__keyword">from</span> db.user;</span></code></pre> </section> <p><span style="color: rgb(36, 41, 47);font-family: sans-serif, -apple-system, BlinkMacSystemFont, &quot;segoe ui&quot;, Helvetica, Arial, &quot;apple color emoji&quot;, &quot;segoe ui emoji&quot;;font-size: 16px;letter-spacing: normal;text-align: start;text-wrap: wrap;background-color: rgb(255, 255, 255);vertical-align: inherit;"></span></p> <p><strong style="letter-spacing: 0.578px;text-wrap: wrap;"><span style="color: rgb(36, 41, 47);font-size: 16px;letter-spacing: normal;text-decoration-style: solid;text-decoration-color: rgb(36, 41, 47);"><span style="letter-spacing: 0.578px;">3.2.3、</span></span></strong><strong style="font-size: var(--articleFontsize);letter-spacing: 0.034em;"><span style="color: rgb(36, 41, 47);font-size: 16px;letter-spacing: normal;text-decoration-style: solid;text-decoration-color: rgb(36, 41, 47);">检查自我</span></strong></p> <section style="line-height: 1.6em;text-align: justify;margin: 0px 0px 24px;text-indent: 0em;"> <span style="color: rgb(36, 41, 47);font-size: 16px;letter-spacing: normal;text-decoration: none solid rgb(36, 41, 47);">&nbsp;&nbsp;&nbsp;&nbsp;当新数据写入表时,Amoro 将自动触发表的自我优化。</span> <span style="color: rgb(36, 41, 47);font-size: 16px;letter-spacing: normal;text-indent: 0em;">点击Tables侧边栏的 ,选择测试表进入表详情页,切换到标签Optimizing页,可以看到该表上所有的自优化任务。</span> </section> <p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100001195" data-ratio="0.3161833489242282" data-s="300,640" src="/upload/80959d90e32b322f2c47cc697501cbbc.png" data-type="png" data-w="1069" style=""></p> <p style="margin-bottom: 16px;color: rgb(36, 41, 47);font-family: sans-serif, -apple-system, BlinkMacSystemFont, &quot;segoe ui&quot;, Helvetica, Arial, &quot;apple color emoji&quot;, &quot;segoe ui emoji&quot;;font-size: 16px;letter-spacing: normal;text-align: start;text-wrap: wrap;background-color: rgb(255, 255, 255);"><span style="vertical-align: inherit;">您也可以</span><code style="font-family: ui-monospace, SFMono-Regular, &quot;SF Mono&quot;, Menlo, Consolas, &quot;Liberation Mono&quot;, monospace;font-size: 13.6px;padding: 0.2em 0.4em;color: rgb(199, 37, 78);background-color: var(--color-neutral-muted);border-radius: 6px;">Optimizing</code><span style="vertical-align: inherit;">通过侧边栏进入页面,查看当前所有表的优化状态。</span></p> <p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-imgfileid="100001196" data-ratio="0.28130841121495326" data-s="300,640" src="/upload/1705c1ffb5834f3ef743e9276c158743.png" data-type="png" data-w="1070" style=""></p> <p><strong style="letter-spacing: 0.578px;text-wrap: wrap;"><span style="font-size: 16px;">四、官网地址:</span></strong><span style="vertical-align: inherit;"></span></p> <blockquote class="js_blockquote_wrap" data-type="2" data-url="" data-author-name="" data-content-utf8-length="4" data-source-title="https://amoro.apache.org/"> <section class="js_blockquote_digest"> <p>官网地址</p> </section> <section class="blockquote_info js_blockquote_source" data-json="%7B%22type%22%3A%22out%22%2C%22source%22%3A%22url%22%2C%22digest%22%3A%22%3Cp%3E%E5%AE%98%E7%BD%91%E5%9C%B0%E5%9D%80%3C%2Fp%3E%22%2C%22digestLen%22%3A4%2C%22text%22%3A%22%22%2C%22article%22%3A%7B%7D%2C%22hasReportOverSize%22%3Afalse%2C%22editorReportData%22%3A%5B%7B%22id%22%3A%22122333%22%2C%22key%22%3A%2276%22%2C%22len%22%3A1%7D%5D%2C%22from%22%3A%22https%3A%2F%2Famoro.apache.org%2F%22%7D"> <span class="blockquote_other">https://amoro.apache.org/</span> </section> </blockquote> <p><br></p> <p><strong style="letter-spacing: 0.578px;text-wrap: wrap;"><span style="font-size: 16px;"><br></span></strong></p> <p><br></p> <p style="display: none;"> <mp-style-type data-value="3"></mp-style-type></p>

10年数仓实战经验,总结出这份ETL干货

作者:微信小助手

<section style="font-size: 14px;letter-spacing: 1px;line-height: 2;"> <section style="font-size: 16px;color: rgb(62, 62, 62);"> <p style="text-wrap: wrap;">ETL一词是Extract、Transform、Load三个英文单词的首字母缩写,中文意为抽取、转换、装载。</p> <p style="text-wrap: wrap;"><strong>1. &nbsp;抽取(Extract):</strong>从多个异构数据源(如数据库、文件、API等)提取数据。这些源系统的数据可能格式各异,结构不同。</p> <p style="text-wrap: wrap;"><strong>2. &nbsp;转换(Transform):</strong>将提取的数据进行清洗和转换,确保数据格式和结构的一致性。这个过程包括数据清洗、数据合并、数据汇总和数据格式转换等,以便于后续的分析和报告。</p> <p style="text-wrap: wrap;"><strong>3. &nbsp;装载(Load):</strong>将转换后的数据加载到数据仓库或数据存储系统中。这一步骤确保数据以适当的形式和结构存储在目标系统中,便于查询和分析。</p> </section> <p style="text-wrap: wrap;"><br></p> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100000614" data-ratio="0.3258145363408521" data-s="300,640" src="/upload/7e6150394163c1408d0b70133f1a83c7.png" data-type="png" data-w="798" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="text-wrap: wrap;"><br></p> <section style="font-size: 16px;"> <p style="text-wrap: wrap;">ETL过程对于数据仓库至关重要,因为它将来自不同源的数据整合到一个统一的结构中,使得数据分析和决策支持变得更加高效和可靠。通过ETL,可以确保数据的质量和一致性,从而提高数据分析的准确性和有效性。</p> </section> <p style="text-wrap: wrap;"><br></p> <section style="text-align: left;justify-content: flex-start;display: flex;flex-flow: row;margin-top: 10px;margin-bottom: 10px;"> <section style="display: inline-block;vertical-align: bottom;width: auto;align-self: flex-end;flex: 0 0 auto;background-color: rgb(33, 120, 240);min-width: 5%;height: auto;padding: 8px;border-right: 0px solid rgba(255, 255, 255, 0);border-top-right-radius: 0px;margin-right: 13px;"> <section style="text-align: justify;font-size: 11px;color: rgb(238, 227, 208);"> <p style="text-wrap: wrap;"><br></p> </section> </section> <section style="display: inline-block;vertical-align: bottom;width: auto;min-width: 5%;flex: 0 0 auto;height: auto;align-self: flex-end;border-bottom: 3px solid rgb(33, 120, 240);border-bottom-right-radius: 0px;background-color: rgba(255, 255, 255, 0);"> <section style="margin-bottom: 6px;"> <section style="text-align: justify;font-size: 17px;"> <p style="text-wrap: wrap;"><strong>数仓架构中的ETL</strong></p> </section> </section> </section> </section> <section style="font-size: 16px;"> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;">可以把数据仓库架构理解成构成数据仓库的组件及其之间的关系,那么就有了下面的数据仓库架构图。</p> </section> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img data-imgfileid="100000618" data-ratio="0.6074074074074074" data-s="300,640" src="/upload/9eeb7b42b507fffdf0e7917dbd11bc85.jpg" data-type="jpeg" data-w="1080" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="text-wrap: wrap;"><br></p> <section style="font-size: 16px;"> <p style="text-wrap: wrap;">图中显示的整个数据仓库环境包括操作型系统和数据仓库系统两大部分。操作型系统的数据由各种形式的业务数据组成,这其中可能包含关系数据库、TXT或CSV文件、HTML或XML文档,还可能存在外部系统的数据,比如网络爬虫抓取来的互联网数据等。数据可能是结构化、半结构化或非结构化的。这些数据经过ETL过程进入数据仓库系统。<br></p> <p style="text-wrap: wrap;">这里把ETL分成了抽取和转换装载两个部分。抽取过程负责从操作型系统获取数据,该过程一般不做数据聚合和汇总,但是会按照主题进行集成,物理上是将操作型系统的数据全量或增量复制到数据仓库系统的RDS中。</p> <p style="text-wrap: wrap;">转换装载过程将数据进行清洗、过滤、汇总、统一格式化等一系列转换操作,使数据转为适合查询的格式,然后装载进数据仓库系统的TDS中。传统数据仓库的基本模式是用一些过程将操作型系统的数据抽取到文件,然后另一些过程将这些文件转化成MySQL或Oracle这样的关系数据库的记录。最后,第三部分过程负责把数据导入进数据仓库。</p> <p style="text-wrap: wrap;"><br></p> </section> <p style="text-wrap: wrap;"><br></p> <section style="text-align: left;justify-content: flex-start;display: flex;flex-flow: row;margin-top: 10px;margin-bottom: 10px;"> <section style="display: inline-block;vertical-align: bottom;width: auto;align-self: flex-end;flex: 0 0 auto;background-color: rgb(33, 120, 240);min-width: 5%;height: auto;padding: 8px;border-right: 0px solid rgba(255, 255, 255, 0);border-top-right-radius: 0px;margin-right: 13px;"> <section style="text-align: justify;font-size: 11px;color: rgb(238, 227, 208);"> <p style="text-wrap: wrap;"><br></p> </section> </section> <section style="display: inline-block;vertical-align: bottom;width: auto;min-width: 5%;flex: 0 0 auto;height: auto;align-self: flex-end;border-bottom: 3px solid rgb(33, 120, 240);border-bottom-right-radius: 0px;background-color: rgba(255, 255, 255, 0);"> <section style="margin-bottom: 6px;"> <section style="text-align: justify;font-size: 17px;"> <p style="text-wrap: wrap;"><strong>数据抽取</strong></p> </section> </section> </section> </section> <p style="text-wrap: wrap;"><br></p> <section style="font-size: 16px;"> <p style="text-wrap: wrap;">抽取操作是ETL处理的第一步,关键在于从源系统获取数据,确保后续转换和装载步骤顺利进行。数据仓库的源系统通常是事务处理应用,如销售订单录入系统,这些系统包含了所有相关记录。设计和建立数据抽取过程通常耗时且复杂,源系统可能缺乏文档且结构复杂。数据抽取需要周期性进行,以保持数据的及时性,且必须不影响源系统的性能或可用性。选择抽取方法时需根据源系统和目标数据仓库的需求进行,通常不允许在源系统中增加额外的逻辑或负担。接下来,将从逻辑和物理两方面介绍数据抽取方法。</p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;"><strong>(1)逻辑抽取</strong></p> <p style="text-wrap: wrap;">有两种逻辑抽取类型:全量抽取和增量抽取。</p> <p style="text-wrap: wrap;"><strong>a.全量抽取</strong></p> <p style="text-wrap: wrap;">源系统的数据全部被抽取。因为这种抽取类型影响源系统上当前所有有效的数据,所以不需要跟踪自上次成功抽取以来的数据变化。源系统只需要原样提供现有的数据而不需要附加的逻辑信息(比如时间戳等)。一个全表导出的数据文件或者一个查询源表所有数据的SQL语句,都是全量抽取的例子。</p> <p style="text-wrap: wrap;"><strong>b.增量抽取</strong></p> <p style="text-wrap: wrap;">只抽取某个事件发生的特定时间点之后的数据。通过该事件发生的时间顺序能够反映数据的历史变化,它可能是最后一次成功抽取,也可能是一个复杂的业务事件,如最后一次财务结算等。必须能够标识出特定时间点之后所有的数据变化。这些发生变化的数据可以由源系统自身来提供,例如能够反映数据最后发生变化的时间戳列,或者是一个原始事务处理之外的,只用于跟踪数据变化的变更日志表。大多数情况下,使用后者意味着需要在源系统上增加数据抽取逻辑。</p> <p style="text-wrap: wrap;">在许多数据仓库中,抽取过程不含任何变化数据捕获技术。取而代之的是,把源系统中的整个表抽取到数据仓库过渡区(Staging Area),然后用这个表的数据和上次从源系统抽取得到的表数据作比对,从而找出发生变化的数据。虽然这种方法不会对源系统造成很大的影响,但显然需要考虑给数据仓库处理增加的负担,尤其是当数据量很大的时候。</p> <p style="text-wrap: wrap;"><br></p> </section> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100000616" data-ratio="0.3851851851851852" data-s="300,640" src="/upload/214b07da6f3def57d333a3136f351bff.png" data-type="png" data-w="1080" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="text-wrap: wrap;"><br></p> <section style="font-size: 16px;"> <p style="text-wrap: wrap;"><strong>(2)物理抽取</strong></p> <p style="text-wrap: wrap;">依赖于选择的逻辑抽取方法,还有能够对源系统所做的操作和所受的限制,存在两种物理数据抽取机制:直接从源系统联机抽取或者间接从一个脱机结构抽取数据。这个脱机结构有可能已经存在,也可能得需要由抽取程序生成。</p> <p style="text-wrap: wrap;"><strong>a.联机抽取</strong></p> <p style="text-wrap: wrap;">数据直接从源系统抽取。抽取进程或者直连源系统数据库访问它们的数据表,或者连接到一个存储快照日志或变更记录的中间层系统(如MySQL数据库的binlog)。注意这个中间层系统并不需要必须和源系统物理分离。</p> <p style="text-wrap: wrap;"><strong>b.脱机抽取</strong></p> <p style="text-wrap: wrap;">数据不从源系统直接抽取,而是从一个源系统以外的过渡区抽取。过渡区可能已经存在(例如数据库备份文件、关系数据库系统的重做日志、归档日志等),或者抽取程序自己建立。</p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;"><strong>(3)变化数据捕获</strong></p> <p style="text-wrap: wrap;">抽取处理需要重点考虑增量抽取,也被称为<strong>变化数据捕获</strong><strong>(Change Data Capture,CDC)</strong>。假设一个数据仓库系统,在每天夜里的业务低峰时间从操作型源系统抽取数据,那么增量抽取只需要过去24小时内发生变化的数据。变化数据捕获也是建立准实时数据仓库的关键技术。</p> <p style="text-wrap: wrap;"><br></p> </section> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100000615" data-ratio="0.587037037037037" data-s="300,640" src="/upload/c526bc5dc106a071060fadc25c1068f7.png" data-type="png" data-w="1080" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="text-wrap: wrap;"><br></p> <section style="font-size: 16px;"> <p style="text-wrap: wrap;">当能够识别并获得最近发生变化的数据时,抽取及其后面的转换、装载操作显然都会变得更高效,因为要处理的数据量会小很多。遗憾的是,很多源系统很难识别出最近变化的数据,或者必须侵入源系统才能做到。变化数据捕获是数据抽取中典型的技术挑战。</p> <p style="text-wrap: wrap;">常用的变化数据捕获方法有时间戳、快照、触发器和日志四种。相信熟悉数据库的用户对这些方法都不会陌生。时间戳方法需要源系统有相应的数据列表示最后的数据变化。快照方法可以使用数据库系统自带的机制实现,如Oracle的物化视图技术,也可以自己实现相关逻辑,但会比较复杂。触发器是关系数据库系统具有的特性,源表上建立的触发器会在对该表执行insert、update、delete等语句时被触发,触发器中的逻辑用于捕获数据的变化。日志可以使用应用日志或系统日志,这种方式对源系统不具有侵入性,但需要额外的日志解析工作。</p> <p style="text-wrap: wrap;"><br></p> </section> <p style="text-wrap: wrap;"><br></p> <section style="text-align: left;justify-content: flex-start;display: flex;flex-flow: row;margin-top: 10px;margin-bottom: 10px;"> <section style="display: inline-block;vertical-align: bottom;width: auto;align-self: flex-end;flex: 0 0 auto;background-color: rgb(33, 120, 240);min-width: 5%;height: auto;padding: 8px;border-right: 0px solid rgba(255, 255, 255, 0);border-top-right-radius: 0px;margin-right: 13px;"> <section style="text-align: justify;font-size: 11px;color: rgb(238, 227, 208);"> <p style="text-wrap: wrap;"><br></p> </section> </section> <section style="display: inline-block;vertical-align: bottom;width: auto;min-width: 5%;flex: 0 0 auto;height: auto;align-self: flex-end;border-bottom: 3px solid rgb(33, 120, 240);border-bottom-right-radius: 0px;background-color: rgba(255, 255, 255, 0);"> <section style="margin-bottom: 6px;"> <section style="text-align: justify;font-size: 17px;"> <p style="text-wrap: wrap;"><strong>数据转换&nbsp;</strong></p> </section> </section> </section> </section> <p style="text-wrap: wrap;"><br></p> <section style="font-size: 16px;"> <p style="text-wrap: wrap;">数据从操作型源系统获取后,需要进行多种转换操作。如统一数据类型、处理拼写错误、消除数据歧义、解析为标准格式等等。数据转换通常是最复杂的部分,也是ETL开发中用时最长的一步。数据转换的范围极广,从单纯的数据类型转化到极为复杂的数据清洗技术。</p> <p style="text-wrap: wrap;">在数据转换阶段,为了能够最终将数据装载到数据仓库中,需要在已经抽取来的数据上应用一系列的规则和函数。有些数据可能不需要转换就能直接导入到数据仓库。</p> <p style="text-wrap: wrap;">数据转换一个最重要的功能是清洗数据,目的是只有“合规”的数据才能进入目标数据仓库。这步操作在不同系统间交互和通信时尤其必要,例如,一个系统的字符集在另一个系统中可能是无效的。另一方面,由于某些业务和技术的需要,也需要进行多种数据转换。</p> </section> <section style="font-size: 16px;"> <p style="text-wrap: wrap;"><br></p> </section> <p style="text-wrap: wrap;"><br></p> <section style="text-align: left;justify-content: flex-start;display: flex;flex-flow: row;margin-top: 10px;margin-bottom: 10px;"> <section style="display: inline-block;vertical-align: bottom;width: auto;align-self: flex-end;flex: 0 0 auto;background-color: rgb(33, 120, 240);min-width: 5%;height: auto;padding: 8px;border-right: 0px solid rgba(255, 255, 255, 0);border-top-right-radius: 0px;margin-right: 13px;"> <section style="text-align: justify;font-size: 11px;color: rgb(238, 227, 208);"> <p style="text-wrap: wrap;"><br></p> </section> </section> <section style="display: inline-block;vertical-align: bottom;width: auto;min-width: 5%;flex: 0 0 auto;height: auto;align-self: flex-end;border-bottom: 3px solid rgb(33, 120, 240);border-bottom-right-radius: 0px;background-color: rgba(255, 255, 255, 0);"> <section style="margin-bottom: 6px;"> <section style="text-align: justify;font-size: 17px;"> <p style="text-wrap: wrap;"><strong>数据装载&nbsp;</strong></p> </section> </section> </section> </section> <p style="text-wrap: wrap;"><br></p> <section style="font-size: 16px;"> <p style="text-wrap: wrap;">ETL的最后步骤是将转换后的数据装载到目标数据仓库中,这一步骤需关注两个主要问题:<strong>装载效率和失败后的重试机制</strong>。</p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;"><strong>●&nbsp;提高装载效率</strong></p> <p style="text-wrap: wrap;">1. 系统资源:确保有足够的系统资源。数据仓库需要高性能的服务器,并且应独占资源,避免与其他系统共享。</p> <p style="text-wrap: wrap;">2. 禁用约束和索引:在装载过程中,禁用数据库的约束(如唯一性、非空性)和索引,待装载完成后再重新启用并重建索引。这可以显著提高装载速度。</p> <p style="text-wrap: wrap;">3. 参考完整性:一般不使用数据库的外键约束来保证数据的完整性,而是由ETL工具或程序来维护。</p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;"><strong>●&nbsp;处理装载失败</strong></p> <p style="text-wrap: wrap;">1. 记录失败点:装载失败时,记录失败点,以便在重新执行时只装载失败的部分。</p> <p style="text-wrap: wrap;">2. 数据更新:如果装载后数据发生变化(如新增或更新数据),需要重新装载过程。</p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;">最终,装载到数据仓库的数据将经过汇总、聚合处理,并交付给多维立方体、数据可视化、仪表盘等工具进行进一步分析。</p> <p style="text-wrap: wrap;"><br></p> </section> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;"><br></p> <section style="text-align: left;justify-content: flex-start;display: flex;flex-flow: row;margin-top: 10px;margin-bottom: 10px;"> <section style="display: inline-block;vertical-align: bottom;width: auto;align-self: flex-end;flex: 0 0 auto;background-color: rgb(33, 120, 240);min-width: 5%;height: auto;padding: 8px;border-right: 0px solid rgba(255, 255, 255, 0);border-top-right-radius: 0px;margin-right: 13px;"> <section style="text-align: justify;font-size: 11px;color: rgb(238, 227, 208);"> <p style="text-wrap: wrap;"><br></p> </section> </section> <section style="display: inline-block;vertical-align: bottom;width: auto;min-width: 5%;flex: 0 0 auto;height: auto;align-self: flex-end;border-bottom: 3px solid rgb(33, 120, 240);border-bottom-right-radius: 0px;background-color: rgba(255, 255, 255, 0);"> <section style="margin-bottom: 6px;"> <section style="text-align: justify;font-size: 17px;"> <p style="text-wrap: wrap;"><strong>ETL工具推荐&nbsp;</strong></p> </section> </section> </section> </section> <p style="text-wrap: wrap;"><br></p> <section style="font-size: 16px;"> <p style="text-wrap: wrap;">市面上常见的数据仓库ETL工具都有自己的功能、优势和支持的数据源。然而,<span style="color: rgb(0, 128, 255);">帆软软件</span>推出的<span style="color: rgb(0, 128, 255);"><strong>FineDataLink</strong></span>以其实时同步和数据质量控制功能脱颖而出。它提供了完整的自助化数据调度与治理平台解决方案,在数据仓库ETL处理方面具有强大的功能和灵活的配置能力,可以帮助企业快速、高效地实现数据仓库ETL处理。</p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;">在数据仓库ETL处理流程中,FineDataLink的优点如下:</p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;"><strong>1. &nbsp;数据抽取:</strong>FineDataLink支持从多种数据源中抽取数据,包括关系型数据库、非关系型数据库、文件、消息队列等。用户可以通过简单的配置,选择需要抽取的数据源和表,并设置抽取规则。</p> </section> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100000617" data-ratio="0.6772151898734177" data-s="300,640" src="/upload/339203f7e5ca7d37243a66762ff7114c.png" data-type="png" data-w="790" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="text-wrap: wrap;"><br></p> <section style="font-size: 16px;"> <p style="text-wrap: wrap;"><strong>2. &nbsp;数据转换:</strong>FineDataLink提供强大的转换功能,支持多种转换操作,包括字段映射、计算、过滤、合并等。用户可以根据具体业务需求进行配置。</p> </section> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100000620" data-ratio="0.7114661654135338" data-s="300,640" src="/upload/b5b16ab70f577fcb79e5a3136b3816e2.png" data-type="png" data-w="1064" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="text-wrap: wrap;"><br></p> <section style="font-size: 16px;"> <p style="text-wrap: wrap;"><strong>3. &nbsp;数据加载:</strong>FineDataLink支持将处理后的数据加载到多种目标系统中,包括关系型数据库、非关系型数据库、文件等。用户可以通过简单的配置,选择需要加载到的目标系统,并设置加载规则。</p> <p style="text-wrap: wrap;"><br></p> <p style="text-wrap: wrap;"><strong>4. &nbsp;调度管理:</strong>FineDataLink提供完善的调度管理功能,支持定时任务和事件触发任务两种方式。用户可以根据具体业务需求进行配置。</p> </section> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100000621" data-ratio="0.6546296296296297" data-s="300,640" src="/upload/2d321d609eb338dc77006235f918b342.png" data-type="png" data-w="1080" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="text-wrap: wrap;"><br></p> <section style="font-size: 16px;"> <p style="text-wrap: wrap;"><strong>5. &nbsp;监控报警:</strong>FineDataLink提供实时监控和报警功能,可以对任务执行情况进行实时监控,并在出现异常情况时及时报警。</p> </section> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img data-imgfileid="100000622" data-ratio="0.5925925925925926" data-s="300,640" src="/upload/55047c8899d03e1a7438c3033bbc9f1b.png" data-type="png" data-w="1080" style="vertical-align: middle;width: 100%;"> </section> </section> <p style="text-wrap: wrap;"><br></p> <section style="font-size: 16px;"> <p style="text-wrap: wrap;">这些功能的集成,使得<span style="color: rgb(33, 120, 240);"><strong>FineDataLink</strong></span>成为一款非常强大的数据仓库ETL工具。此外,FineDataLink还提供了一些高级功能,如并行处理、增量更新、数据质量检查等。借助这款工具,企业可以确保其数据可靠、准确并且易于访问以进行分析和决策。</p> </section> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;"> <img class="rich_pages wxw-img" data-imgfileid="100000623" data-ratio="0.47962962962962963" data-s="300,640" src="/upload/a7e7817cb507ed1e9953721726214af1.png" data-type="png" data-w="1080" style="vertical-align: middle;width: 100%;"> </section> </section> <section style="text-wrap: wrap;line-height: 3em;"> <strong style="font-size: 16px;background-color: rgb(255, 255, 255);font-family: &quot;PingFang SC&quot;, system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;outline: 0px;"></strong> <br> </section> <section style="text-wrap: wrap;line-height: 3em;"> <strong style="font-size: 16px;background-color: rgb(255, 255, 255);font-family: &quot;PingFang SC&quot;, system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;outline: 0px;">往期推荐:</strong> </section> <section style="margin-top: 15px;margin-bottom: 15px;outline: 0px;font-family: &quot;PingFang SC&quot;, system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 14px;letter-spacing: 1px;text-wrap: wrap;background-color: rgb(255, 255, 255);justify-content: flex-start;display: flex;flex-flow: row;"> <section style="outline: 0px;display: inline-block;vertical-align: top;width: auto;min-width: 10%;flex: 0 0 auto;height: auto;align-self: flex-start;"> <p style="outline: 0px;"><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzkwMDcyMTQ3OQ==&amp;mid=2247484197&amp;idx=1&amp;sn=f455494717cbf2a0cc7252c33f6429cc&amp;chksm=c0befd0df7c9741bd44ae899fba9f8dcd455bb1c281b342fa09e7307d2bdaa60d66b26f1536a&amp;scene=21#wechat_redirect" textvalue="关于数据清洗的六个问题" linktype="text" imgurl="" imgdata="null" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="outline: 0px;color: var(--weui-LINK);cursor: default;font-size: 15px;"><strong><span style="font-size: 15px;">关于数据清洗的六个问题</span></strong></a></p> </section> </section> <section style="margin-top: 15px;margin-bottom: 15px;outline: 0px;font-family: &quot;PingFang SC&quot;, system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 14px;letter-spacing: 1px;text-wrap: wrap;background-color: rgb(255, 255, 255);justify-content: flex-start;display: flex;flex-flow: row;"> <section style="outline: 0px;display: inline-block;vertical-align: top;width: auto;min-width: 10%;flex: 0 0 auto;height: auto;align-self: flex-start;"> <p style="outline: 0px;"><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzkwMDcyMTQ3OQ==&amp;mid=2247484130&amp;idx=1&amp;sn=068732955eb30ec0248cbae187e4b4ac&amp;chksm=c0befccaf7c975dccbb9fc25d5b011cbc35ea62ec6d9e6f35724ec9dc54c6c6b589b695ee7f0&amp;scene=21#wechat_redirect" textvalue="终于有人把ETL增量抽取讲明白了" linktype="text" imgurl="" imgdata="null" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="outline: 0px;color: var(--weui-LINK);cursor: default;font-size: 15px;"><strong><span style="font-size: 15px;">终于有人把ETL增量抽取讲明白了</span></strong></a></p> </section> </section> <section style="margin-top: 15px;margin-bottom: 15px;outline: 0px;font-family: &quot;PingFang SC&quot;, system-ui, -apple-system, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 14px;letter-spacing: 1px;text-wrap: wrap;background-color: rgb(255, 255, 255);justify-content: flex-start;display: flex;flex-flow: row;"> <section style="outline: 0px;display: inline-block;vertical-align: top;width: auto;min-width: 10%;flex: 0 0 auto;height: auto;align-self: flex-start;"> <p style="outline: 0px;"><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzkwMDcyMTQ3OQ==&amp;mid=2247483977&amp;idx=1&amp;sn=d2ce42f26b27b93be54dfd99223975b6&amp;chksm=c0befc61f7c975775f15bb2ac15278c50545fe7113012a8d2d733aa327f7770f8a57ba35fec4&amp;scene=21#wechat_redirect" textvalue="看完了这篇实时数仓建设,才发现以前的都白看了" linktype="text" imgurl="" imgdata="null" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="outline: 0px;color: var(--weui-LINK);cursor: default;"><strong><span style="outline: 0px;color: var(--weui-LINK);cursor: default;font-size: 15px;">看完了这篇实时数仓建设,才发现以前的都白看了</span></strong></a></p> </section> </section> <section style="text-wrap: wrap;line-height: 3em;"> <br> </section> <section style="font-size: 16px;"> <p style="text-wrap: wrap;"><strong>了解更多资讯请关注:</strong></p> <p style="text-wrap: wrap;"><strong><br></strong></p> <section class="mp_profile_iframe_wrp"> <mp-common-profile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-id="MzkwMzMxNjIwMg==" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/OQWqPWFuqJtOWiaCEUzIENA0NBDLP1dV5ibael9LdTbURB8D5ahDgicdic9GVGic6icEnePbab023AzFz6OWffrrJoWA/0?wx_fmt=png" data-nickname="FineDataLink" data-alias="fdl_dataplatform" data-signature="FineDataLink,“快速、高效、易用”的企业级一站式数据集成平台。" data-from="0" data-is_biz_ban="0"></mp-common-profile> </section> <section> <br> </section> </section> <p style="text-wrap: wrap;"><br></p> <section style="margin: 10px 0%;text-align: left;justify-content: flex-start;display: flex;flex-flow: row;"> <section style="display: inline-block;vertical-align: middle;width: 12%;align-self: center;flex: 0 0 auto;"> <section style="text-align: center;margin-right: 0%;margin-left: 0%;line-height: 0;"> <section style="vertical-align: middle;display: inline-block;line-height: 0;width: 100%;"> <img class="rich_pages wxw-img" data-imgfileid="100000619" data-ratio="1" data-s="300,640" src="/upload/8fc4b234cc27848bdb051919ececdda0.png" data-type="gif" data-w="300" style="vertical-align: middle;width: 100%;"> </section> </section> </section> <section style="display: inline-block;vertical-align: middle;width: 88%;padding-left: 10px;align-self: center;flex: 0 0 auto;"> <section style="margin-right: 0%;margin-left: 0%;"> <section style="text-align: justify;"> <p style="text-wrap: wrap;">点击<strong style="color: rgb(0, 69, 128);">“阅读原文”<span style="color: rgb(62, 62, 62);">,申请试用FineDataLink</span></strong></p> </section> </section> </section> </section> </section> <p style="display: none;"> <mp-style-type data-value="3"></mp-style-type></p>

业务实战-如何搭建知识图谱?

作者:微信小助手

<p style="text-align: left;margin-bottom: 8px;line-height: 1.75em;"><span style="outline: 0px;color: rgb(121, 123, 170);visibility: visible;"><img class="rich_pages wxw-img" data-backh="278" data-backw="578" data-imgfileid="502712608" data-ratio="0.48055555555555557" data-type="png" data-w="1080" style="color: rgb(89, 89, 89);font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;text-align: left;text-wrap: wrap;outline: 0px;width: 100%;visibility: visible !important;height: auto !important;" src="/upload/2d0c1dc2603e8fcb80d79abbc5bd63c2.png"></span></p> <p style="text-align: left;line-height: 1.5em;margin-bottom: 8px;"><span style="color: rgb(121, 123, 170);font-size: 14px;"><span style="color: rgb(121, 123, 170);outline: 0px;visibility: visible;">原文作者:</span>白白的一团团</span></p> <p style="outline: 0px;color: rgba(0, 0, 0, 0.55);font-family: &quot;PingFang SC&quot;, system-ui, -apple-system, &quot;system-ui&quot;, &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);visibility: visible;text-align: left;line-height: 1.5em;margin-bottom: 8px;"><span style="outline: 0px;visibility: visible;color: rgb(121, 123, 170);font-size: 14px;">原文链接 :https://blog.csdn.net/baidu_39413110/article/details/123142066</span></p> <p style="outline: 0px;color: rgba(0, 0, 0, 0.55);font-family: &quot;PingFang SC&quot;, system-ui, -apple-system, &quot;system-ui&quot;, &quot;Helvetica Neue&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);visibility: visible;text-align: left;line-height: 1.5em;margin-bottom: 8px;"><span style="outline: 0px;visibility: visible;color: rgb(121, 123, 170);font-size: 14px;"><br></span></p> <p style="outline: 0px;visibility: visible;margin-bottom: 8px;line-height: 1.75em;"><span style="outline: 0px;letter-spacing: 2px;background-color: rgb(0, 122, 170);color: rgb(255, 255, 255);visibility: visible;"><strong style="outline: 0px;visibility: visible;">目&nbsp; 录</strong></span></p> <blockquote class="js_blockquote_wrap" data-type="2" data-url="" data-author-name="" data-content-utf8-length="175" data-source-title="" data-text="一、如何构建知识图谱&nbsp;&nbsp;&nbsp;&nbsp;1、搭建知识图谱需要哪些数据&nbsp;&nbsp;&nbsp;&nbsp;2、如何设计知识图谱结构&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;2.1 隐性申请节点结构&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;2.2 显性申请节点结构&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;2.3 两种知识图谱结构的特点对比二、知识图谱的优势&nbsp;&nbsp;&nbsp;&nbsp;1、提高聚集变量计算效率&nbsp;&nbsp;&nbsp;&nbsp;2、实现异常团簇的敏捷识别&nbsp;&nbsp;&nbsp;&nbsp;3、为关联关系的深度挖掘提供平台三、知识图谱如何应用及常见问题&nbsp;&nbsp;&nbsp;&nbsp;1、图谱应用方式&nbsp;&nbsp;&nbsp;&nbsp;2、知识图谱回溯问题&nbsp;&nbsp;&nbsp;&nbsp;3、知识图谱防范团伙欺诈的及时性问题" data-editid="rx9uc5kiqv42et7ym8"> <section class="js_blockquote_digest"> <section> <p style="outline: 0px;visibility: visible;margin-bottom: 8px;line-height: 1.75em;"><strong><span style="outline: 0px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 2px;text-align: left;background-color: rgb(255, 255, 255);font-size: 15px;visibility: visible;color: rgb(121, 123, 170);">一、如何构建知识图谱</span></strong></p> <p style="outline: 0px;visibility: visible;margin-bottom: 8px;line-height: 1.75em;"><span style="color: rgb(121, 123, 170);">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 2px;text-align: left;background-color: rgb(255, 255, 255);font-size: 15px;visibility: visible;">1、搭建知识图谱需要哪些数据</span></span></p> <p style="outline: 0px;visibility: visible;margin-bottom: 8px;line-height: 1.75em;"><span style="color: rgb(121, 123, 170);">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 2px;text-align: left;background-color: rgb(255, 255, 255);font-size: 15px;visibility: visible;">2、如何设计知识图谱结构</span></span></p> <p style="outline: 0px;visibility: visible;margin-bottom: 8px;line-height: 1.75em;"><span style="color: rgb(121, 123, 170);">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="outline: 0px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 2px;text-align: left;background-color: rgb(255, 255, 255);font-size: 15px;visibility: visible;">2.1 隐性申请节点结构</span></span></p> <p style="outline: 0px;visibility: visible;margin-bottom: 8px;line-height: 1.75em;"><span style="color: rgb(121, 123, 170);">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="outline: 0px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 2px;text-align: left;background-color: rgb(255, 255, 255);font-size: 15px;visibility: visible;">2.2 显性申请节点结构</span></span></p> <p style="outline: 0px;visibility: visible;margin-bottom: 8px;line-height: 1.75em;"><span style="color: rgb(121, 123, 170);">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="outline: 0px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 2px;text-align: left;background-color: rgb(255, 255, 255);font-size: 15px;visibility: visible;">2.3 两种知识图谱结构的特点对比</span></span></p> <p style="margin-top: 8px;outline: 0px;visibility: visible;margin-bottom: 8px;line-height: 1.75em;"><strong><span style="outline: 0px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 2px;text-align: left;background-color: rgb(255, 255, 255);font-size: 15px;visibility: visible;color: rgb(121, 123, 170);">二、知识图谱的优势</span></strong></p> <p style="outline: 0px;margin-bottom: 8px;line-height: 1.75em;"><span style="color: rgb(121, 123, 170);">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 2px;text-align: left;background-color: rgb(255, 255, 255);font-size: 15px;">1、提高聚集变量计算效率</span></span></p> <p style="outline: 0px;margin-bottom: 8px;line-height: 1.75em;"><span style="color: rgb(121, 123, 170);">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 2px;text-align: left;background-color: rgb(255, 255, 255);font-size: 15px;">2、实现异常团簇的敏捷识别</span></span></p> <p style="outline: 0px;margin-bottom: 8px;line-height: 1.75em;"><span style="color: rgb(121, 123, 170);">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 2px;text-align: left;background-color: rgb(255, 255, 255);font-size: 15px;">3、为关联关系的深度挖掘提供平台</span></span></p> <p style="margin-top: 8px;outline: 0px;margin-bottom: 8px;line-height: 1.75em;"><strong><span style="outline: 0px;background-color: rgb(255, 255, 255);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;text-align: left;color: rgb(121, 123, 170);">三、知识图谱如何应用及常见问题</span></strong></p> <p style="outline: 0px;margin-bottom: 8px;line-height: 1.75em;"><span style="color: rgb(121, 123, 170);">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 2px;text-align: left;background-color: rgb(255, 255, 255);font-size: 15px;">1、图谱应用方式</span></span></p> <p style="outline: 0px;margin-bottom: 8px;line-height: 1.75em;"><span style="color: rgb(121, 123, 170);">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 2px;text-align: left;background-color: rgb(255, 255, 255);font-size: 15px;">2、知识图谱回溯问题</span></span></p> <p style="outline: 0px;margin-bottom: 8px;line-height: 1.75em;"><span style="color: rgb(121, 123, 170);">&nbsp;&nbsp;&nbsp;&nbsp;<span style="outline: 0px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 2px;text-align: left;background-color: rgb(255, 255, 255);font-size: 15px;">3、知识图谱防范团伙欺诈的及时性问题</span></span></p> </section> </section> </blockquote> <p style="line-height: 1.75em;margin-bottom: 16px;"><br></p> <p style="outline: 0px;line-height: 1.75em;margin-bottom: 16px;"><span style="outline: 0px;color: rgb(89, 89, 89);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 2px;text-align: left;background-color: rgb(255, 255, 255);font-size: 15px;">脱胎于搜索引擎优化的知识图谱技术,本质上是一种揭示实体关系的信息网络,如今已广泛应用于各个领域。在信贷领域,知识图谱也经常被各家机构标榜为一种先进的大数据应用技术。在流量红利时代成为过去式后,信贷领域会越来越强调对客户的精细化运营,即对客户要做到千人千面的定制化服务和策略,这就要求信贷机构对客户要有360度全景式的把握,不仅要掌握客户的基本信息、行为偏好、金融特征,更要掌握客户间的关联关系和信贷申请行为的聚集性特征,而知识图谱在识别客户关系和聚集性特征方面就有着不可替代的优势。</span></p> <p style="outline: 0px;line-height: 1.75em;margin-bottom: 16px;text-align: left;"><span style="outline: 0px;color: rgb(89, 89, 89);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 2px;text-align: left;background-color: rgb(255, 255, 255);font-size: 15px;">所以今天我们就简单聊一聊关于知识图谱的几个问题,一,如何构建一个契合信贷业务的知识图谱;二,知识图谱在信贷业务中的应用优势有哪些;三,如何应用这项技术去赋能信贷业务;以及四,知识图谱应用中需要注意的一些问题。如果想深入的挖掘,可以参考下我的课程:<a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzA4OTAwMjY2Nw==&amp;mid=2650196263&amp;idx=1&amp;sn=5b0930b7f8f7ee21815b5b356f648824&amp;chksm=8823eee3bf5467f52d13cf86d3cc472d6126f79adddde472c378e4eb3a66310ed23a318cca72&amp;scene=21#wechat_redirect" textvalue="万物皆网络-风控中的网络挖掘方法" linktype="text" imgurl="" imgdata="null" data-itemshowtype="0" tab="innerlink" data-linktype="2">万物皆网络-风控中的网络挖掘方法</a></span></p> <p style="outline: 0px;line-height: 1.75em;margin-bottom: 16px;"><span style="outline: 0px;color: rgb(89, 89, 89);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 2px;text-align: left;background-color: rgb(255, 255, 255);font-size: 15px;"><br></span></p> <p style="line-height: 1.75em;margin-bottom: 16px;"><span style="font-size: 24px;"><strong><span style="color: rgb(0, 82, 255);">一、如何构建知识图谱?</span></strong></span></p> <p style="outline: 0px;line-height: 1.75em;margin-bottom: 16px;"><span style="outline: 0px;font-size: 18px;"><strong style="outline: 0px;">1、搭建知识图谱需要哪些数据</strong></span></p> <p style="outline: 0px;line-height: 1.75em;margin-bottom: 16px;"><span style="outline: 0px;color: rgb(89, 89, 89);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 2px;text-align: left;background-color: rgb(255, 255, 255);font-size: 15px;">搭建知识图谱的目的之一在于完全挖掘出客户间各种错综复杂的关联关系,所以原则上就需要把各种有关联可能的数据都纳入进来。另一方面,我们同样需要把客户的身份标识数据、重要属性特征也纳入进来,便于后续我们对客户关系的分析、回溯及关联变量的加工。所以我们从关联数据、重要属性两个维度展开来讲。</span></p> <p style="outline: 0px;line-height: 1.75em;margin-bottom: 16px;"><span style="outline: 0px;font-size: 18px;"><strong style="outline: 0px;">关联数据主要包括这几个维度:</strong></span></p> <p style="outline: 0px;line-height: 1.75em;margin-bottom: 16px;"><strong><span style="outline: 0px;color: rgb(89, 89, 89);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 2px;text-align: left;background-color: rgb(255, 255, 255);font-size: 15px;">手机号码:</span></strong><span style="outline: 0px;background-color: rgb(255, 255, 255);color: rgb(89, 89, 89);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;letter-spacing: 2px;text-align: left;">包括客户的注册手机号、用款手机号、紧急联系人手机号、配偶手机号、亲属手机号、公司电话、家庭电话、人行报告中近期曾使用电话,以及现在变得异常敏感的通讯录�

MySQL 日志详解

作者:微信小助手

<p style="margin-top: 15px;margin-bottom: 15px;color: rgb(68, 68, 68);font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;font-size: 14px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">MySQL日志是数据库管理中的重要组成部分,它记录了数据库运行过程中的各种状态信息,对于异常排查、性能优化、数据恢复和备份等方面起着关键作用。以下是对MySQL日志的详细解析及案例分析:</p> <h2 style="margin-top: 25px;margin-bottom: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;color: rgb(68, 68, 68);font-size: 24px;line-height: 30px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">一、MySQL日志类型</h2> <p style="margin-top: 15px;margin-bottom: 15px;color: rgb(68, 68, 68);font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;font-size: 14px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">MySQL日志主要分为两大类:Server层日志和引擎层日志(本文主要讨论InnoDB引擎)。Server层日志包括错误日志、二进制日志、查询日志、慢查询日志等;引擎层日志则主要涉及InnoDB的重做日志(Redo Log)和撤销日志(Undo Log)。</p> <p style="margin-top: 15px;margin-bottom: 15px;color: rgb(68, 68, 68);font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;font-size: 14px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"><img class="rich_pages wxw-img" data-imgfileid="100000441" data-ratio="0.48333333333333334" src="/upload/a8a79e9842c7a156cba98411beca3305.jpg" data-type="jpeg" data-w="1080"></p> <h3 style="margin-top: 25px;margin-bottom: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;color: rgb(68, 68, 68);font-size: 18px;line-height: 24px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">1.&nbsp;<span style="font-weight: 700;">错误日志(Error Log)</span></h3> <ul style="margin-top: 15px;margin-bottom: 15px;padding-left: 30px;color: rgb(68, 68, 68);font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;font-size: 14px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);" class="list-paddingleft-1"> <li><p><span style="font-weight: 700;">作用</span>:记录MySQL Server启动、运行或停止时出现的问题,如数据库启动失败、连接错误、SQL语句错误等。</p></li> <li><p><span style="font-weight: 700;">案例</span>:假设MySQL Server因磁盘空间不足而启动失败,相关信息会记录在错误日志中,管理员可通过查看错误日志找到问题根源并解决。</p></li> <li><p><span style="font-weight: 700;">查看方式</span>:可通过配置文件中的<code style="font-size: 12px;font-family: Consolas, monospace, serif;color: rgb(221, 0, 85);white-space: nowrap;padding-right: 4px;padding-left: 4px;border-width: 1px;border-style: solid;border-color: rgb(221, 221, 221);border-radius: 3px;background: rgb(250, 250, 250);">log-error</code>参数指定错误日志文件的路径,或使用默认路径(如<code style="font-size: 12px;font-family: Consolas, monospace, serif;color: rgb(221, 0, 85);white-space: nowrap;padding-right: 4px;padding-left: 4px;border-width: 1px;border-style: solid;border-color: rgb(221, 221, 221);border-radius: 3px;background: rgb(250, 250, 250);">/var/log/mysqld.log</code>)。</p></li> </ul> <p style="margin-top: 15px;margin-bottom: 15px;color: rgb(68, 68, 68);font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;font-size: 14px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"><img class="rich_pages wxw-img" data-imgfileid="100000439" data-ratio="0.36203703703703705" src="/upload/7c547db9164e25446ca537d1ca2fcde3.png" data-type="png" data-w="1080" style="vertical-align: middle;border-width: 0px;border-style: initial;border-color: initial;"></p> <h3 style="margin-top: 25px;margin-bottom: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;color: rgb(68, 68, 68);font-size: 18px;line-height: 24px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">2.&nbsp;<span style="font-weight: 700;">二进制日志(Binary Log, Binlog)</span></h3> <ul style="margin-top: 15px;margin-bottom: 15px;padding-left: 30px;color: rgb(68, 68, 68);font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;font-size: 14px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);" class="list-paddingleft-1"> <li><p><span style="font-weight: 700;">作用</span>:主要作用有两个,分别是 主从复制 和 数据恢复 。</p></li> <ul style="padding-left: 30px;list-style-type: square;" class="list-paddingleft-1"> <li><p><span style="font-weight: 700;">主从复制</span>&nbsp;:在 Master 端开启 binlog ,然后将 binlog发送到各个 Slave 端, Slave 端重放 binlog 从而达到主从数据一致。</p></li> <li><p><span style="font-weight: 700;">数据恢复</span>&nbsp;:通过使用 mysqlbinlog 工具来恢复数据。</p></li> </ul> <li><p><span style="font-weight: 700;">binlog 记录方式</span>:</p></li> <ul style="padding-left: 30px;list-style-type: square;" class="list-paddingleft-1"> <li><p>binlog 用于记录数据库执行的写入性操作(不包括查询)信息,以二进制的形式保存在磁盘中。binlog 是 mysql的逻辑日志,并且由 Server 层进行记录,使用任何存储引擎的 mysql 数据库都会记录 binlog 日志。</p></li> <li><p>binlog 是通过追加的方式进行写入的,可以通过max_binlog_size 参数设置每个 binlog文件的大小,当文件大小达到给定值之后,会生成新的文件来保存日志。</p></li> </ul> <li><p><span style="font-weight: 700;">格式</span>:包括基于语句的格式(Statement)、基于行的格式(Row)和混合模式(Mixed)。</p></li> <li><p><span style="font-weight: 700;">查看方式</span>:可通过<code style="font-size: 12px;font-family: Consolas, monospace, serif;color: rgb(221, 0, 85);white-space: nowrap;padding-right: 4px;padding-left: 4px;border-width: 1px;border-style: solid;border-color: rgb(221, 221, 221);border-radius: 3px;background: rgb(250, 250, 250);">mysqlbinlog</code>工具查看Binlog内容。</p></li> </ul> <h3 style="margin-top: 25px;margin-bottom: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;color: rgb(68, 68, 68);font-size: 18px;line-height: 24px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">3.&nbsp;<span style="font-weight: 700;">查询日志(General Log)</span></h3> <ul style="margin-top: 15px;margin-bottom: 15px;padding-left: 30px;color: rgb(68, 68, 68);font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;font-size: 14px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);" class="list-paddingleft-1"> <li><p><span style="font-weight: 700;">作用</span>:记录MySQL Server接收到的每一个客户端请求,包括连接和断开连接信息、执行的查询语句等。主要用于排错和调试。</p></li> <li><p><span style="font-weight: 700;">案例</span>:当需要追踪某个特定查询的来源或执行时间时,可启用查询日志进行记录。</p></li> <li><p><span style="font-weight: 700;">启用与配置</span>:通过配置文件中的<code style="font-size: 12px;font-family: Consolas, monospace, serif;color: rgb(221, 0, 85);white-space: nowrap;padding-right: 4px;padding-left: 4px;border-width: 1px;border-style: solid;border-color: rgb(221, 221, 221);border-radius: 3px;background: rgb(250, 250, 250);">general_log</code>和<code style="font-size: 12px;font-family: Consolas, monospace, serif;color: rgb(221, 0, 85);white-space: nowrap;padding-right: 4px;padding-left: 4px;border-width: 1px;border-style: solid;border-color: rgb(221, 221, 221);border-radius: 3px;background: rgb(250, 250, 250);">general_log_file</code>参数启用和配置查询日志。</p></li> </ul> <h3 style="margin-top: 25px;margin-bottom: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;color: rgb(68, 68, 68);font-size: 18px;line-height: 24px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">4.&nbsp;<span style="font-weight: 700;">慢查询日志(Slow Query Log)</span></h3> <ul style="margin-top: 15px;margin-bottom: 15px;padding-left: 30px;color: rgb(68, 68, 68);font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;font-size: 14px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);" class="list-paddingleft-1"> <li><p><span style="font-weight: 700;">作用</span>:记录执行时间超过设定阈值(如10秒)的查询语句,帮助管理员发现性能瓶颈并进行优化。</p></li> <li><p><span style="font-weight: 700;">案例</span>:通过分析慢查询日志,发现某个查询语句执行时间过长,可能是由于缺少有效索引或查询条件不合理等原因造成的。</p></li> <li><p><span style="font-weight: 700;">启用与配置</span>:通过配置文件中的<code style="font-size: 12px;font-family: Consolas, monospace, serif;color: rgb(221, 0, 85);white-space: nowrap;padding-right: 4px;padding-left: 4px;border-width: 1px;border-style: solid;border-color: rgb(221, 221, 221);border-radius: 3px;background: rgb(250, 250, 250);">slow_query_log</code>、<code style="font-size: 12px;font-family: Consolas, monospace, serif;color: rgb(221, 0, 85);white-space: nowrap;padding-right: 4px;padding-left: 4px;border-width: 1px;border-style: solid;border-color: rgb(221, 221, 221);border-radius: 3px;background: rgb(250, 250, 250);">slow_query_log_file</code>和<code style="font-size: 12px;font-family: Consolas, monospace, serif;color: rgb(221, 0, 85);white-space: nowrap;padding-right: 4px;padding-left: 4px;border-width: 1px;border-style: solid;border-color: rgb(221, 221, 221);border-radius: 3px;background: rgb(250, 250, 250);">long_query_time</code>参数启用和配置慢查询日志。</p></li> </ul> <h3 style="margin-top: 25px;margin-bottom: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;color: rgb(68, 68, 68);font-size: 18px;line-height: 24px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">5.&nbsp;<span style="font-weight: 700;">重做日志(Redo Log)</span></h3> <ul style="margin-top: 15px;margin-bottom: 15px;padding-left: 30px;color: rgb(68, 68, 68);font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;font-size: 14px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);" class="list-paddingleft-1"> <li><p><span style="font-weight: 700;">作用</span>:记录事务过程中的修改操作,并在系统崩溃时用于恢复数据,以保证事务的持久性。</p></li> <li><p><span style="font-weight: 700;">案例</span>:在InnoDB存储引擎中,重做日志是事务处理的关键部分,用于在系统故障后重放事务,以恢复数据的一致性。</p></li> <li><p><span style="font-weight: 700;">管理</span>:重做日志的生成和管理由InnoDB存储引擎自动完成,用户无需直接干预。</p></li> </ul> <h3 style="margin-top: 25px;margin-bottom: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;color: rgb(68, 68, 68);font-size: 18px;line-height: 24px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">6.&nbsp;<span style="font-weight: 700;">撤销日志(Undo Log)</span></h3> <ul style="margin-top: 15px;margin-bottom: 15px;padding-left: 30px;color: rgb(68, 68, 68);font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;font-size: 14px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);" class="list-paddingleft-1"> <li><p><span style="font-weight: 700;">作用</span>:用于撤销与事务相关的修改操作,以保证事务的原子性。在事务回滚时,撤销日志被用来恢复数据到事务开始前的状态。</p></li> <li><p><span style="font-weight: 700;">案例</span>:当事务执行失败需要回滚时,撤销日志中的信息被用来撤销事务中的所有修改操作。</p></li> <li><p><span style="font-weight: 700;">管理</span>:撤销日志的生成和管理同样由InnoDB存储引擎自动完成。</p></li> </ul> <h2 style="margin-top: 25px;margin-bottom: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;color: rgb(68, 68, 68);font-size: 24px;line-height: 30px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">二、Redo log和Binlog的区别</h2> <p style="margin-top: 15px;margin-bottom: 15px;color: rgb(68, 68, 68);font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;font-size: 14px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">MySQL中的Redo log(重做日志)和Binlog(二进制日志)是两种不同类型的日志,它们在数据库系统中扮演着不同的角色,主要存在以下几个方面的区别:</p> <h3 style="margin-top: 25px;margin-bottom: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;color: rgb(68, 68, 68);font-size: 18px;line-height: 24px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">1.&nbsp;<span style="font-weight: 700;">使用场景与功能</span></h3> <ul style="margin-top: 15px;margin-bottom: 15px;padding-left: 30px;color: rgb(68, 68, 68);font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;font-size: 14px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);" class="list-paddingleft-1"> <li><p style="margin-bottom: 15px;"><span style="font-weight: 700;">Redo Log</span>:</p></li> <ul style="padding-left: 30px;list-style-type: square;" class="list-paddingleft-1"> <li><p>主要用于保证InnoDB存储引擎的事务持久性和一致性。</p></li> <li><p>在数据库崩溃或意外关闭时,通过Redo Log来恢复未完成的事务,确保数据的完整性和持久性。</p></li> <li><p>它是物理日志,记录的是数据页的物理变化,即“在某个数据页上做了什么修改”。</p></li> </ul> <li><p style="margin-bottom: 15px;"><span style="font-weight: 700;">Binlog</span>:</p></li> <ul style="padding-left: 30px;list-style-type: square;" class="list-paddingleft-1"> <li><p>主要用于数据备份、数据恢复和数据同步(如主从复制)。</p></li> <li><p>记录的是对数据库执行的逻辑变化,如SQL语句的原始文本,包括数据定义语言(DDL)和数据操作语言(DML)的更改。</p></li> <li><p>它不仅限于InnoDB存储引擎,MySQL的Server层实现,所有引擎都可以使用。</p></li> </ul> </ul> <h3 style="margin-top: 25px;margin-bottom: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;color: rgb(68, 68, 68);font-size: 18px;line-height: 24px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">2.&nbsp;<span style="font-weight: 700;">记录内容与格式</span></h3> <ul style="margin-top: 15px;margin-bottom: 15px;padding-left: 30px;color: rgb(68, 68, 68);font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;font-size: 14px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);" class="list-paddingleft-1"> <li><p style="margin-bottom: 15px;"><span style="font-weight: 700;">Redo Log</span>:</p></li> <ul style="padding-left: 30px;list-style-type: square;" class="list-paddingleft-1"> <li><p>记录的是物理变化,即数据页的变化结果。</p></li> <li><p>每条Redo记录由“表空间号+数据页号+偏移量+修改数据长度+具体修改的数据”组成。</p></li> </ul> <li><p style="margin-bottom: 15px;"><span style="font-weight: 700;">Binlog</span>:</p></li> <ul style="padding-left: 30px;list-style-type: square;" class="list-paddingleft-1"> <li><p>记录的是逻辑变化,即SQL语句的原始逻辑。</p></li> <li><p>提供三种日志格式:Statement、Row以及Mixed。Statement格式记录的是修改数据的SQL语句;Row格式记录的是哪条记录被修改成了什么样子;Mixed则是前两者的混合。</p></li> </ul> </ul> <h3 style="margin-top: 25px;margin-bottom: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;color: rgb(68, 68, 68);font-size: 18px;line-height: 24px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">3.&nbsp;<span style="font-weight: 700;">写入方式与时机</span></h3> <ul style="margin-top: 15px;margin-bottom: 15px;padding-left: 30px;color: rgb(68, 68, 68);font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;font-size: 14px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);" class="list-paddingleft-1"> <li><p style="margin-bottom: 15px;"><span style="font-weight: 700;">Redo Log</span>:</p></li> <ul style="padding-left: 30px;list-style-type: square;" class="list-paddingleft-1"> <li><p>是在InnoDB存储引擎层面的操作,由后台线程生成并写入到磁盘中。</p></li> <li><p>写入时机可以根据innodb_flush_log_at_trx_commit参数配置,支持三种策略:0、1、2。默认为1,即每次事务提交时都进行刷盘操作。</p></li> <li><p>以循环写入的方式记录,当日志写满时,会从头开始覆盖之前的日志。</p></li> </ul> <li><p style="margin-bottom: 15px;"><span style="font-weight: 700;">Binlog</span>:</p></li> <ul style="padding-left: 30px;list-style-type: square;" class="list-paddingleft-1"> <li><p>是在执行SQL语句时,在主线程中生成逻辑变化并写入到磁盘中。</p></li> <li><p>写入时机通常是在事务提交时,但也可以通过配置来控制刷盘的频率。</p></li> <li><p>以追加写入的方式记录,即每次写入都追加到日志的末尾,不会覆盖之前的日志。</p></li> </ul> </ul> <h3 style="margin-top: 25px;margin-bottom: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;color: rgb(68, 68, 68);font-size: 18px;line-height: 24px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">4.&nbsp;<span style="font-weight: 700;">性能影响</span></h3> <ul style="margin-top: 15px;margin-bottom: 15px;padding-left: 30px;color: rgb(68, 68, 68);font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;font-size: 14px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);" class="list-paddingleft-1"> <li><p style="margin-bottom: 15px;"><span style="font-weight: 700;">Redo Log</span>:</p></li> <ul style="padding-left: 30px;list-style-type: square;" class="list-paddingleft-1"> <li><p>由于是物理日志且通过顺序IO操作写入,因此具有较低的开销,有助于提高数据库的写入性能。</p></li> </ul> <li><p style="margin-bottom: 15px;"><span style="font-weight: 700;">Binlog</span>:</p></li> <ul style="padding-left: 30px;list-style-type: square;" class="list-paddingleft-1"> <li><p>由于是逻辑日志且可能涉及随机IO操作(如根据SQL语句定位到具体的数据页),因此相对于Redo Log会有更高的开销。</p></li> </ul> </ul> <p style="margin-top: 15px;margin-bottom: 15px;color: rgb(68, 68, 68);font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;font-size: 14px;letter-spacing: normal;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">综上所述,Redo Log和Binlog在MySQL中各有其独特的作用和优势,它们共同协作以确保数据库的数据完整性和一致性。</p> <p><br></p> <p style="display: none;"> <mp-style-type data-value="3"></mp-style-type></p>