{
    "componentChunkName": "component---src-templates-blog-blog-tsx",
    "path": "/blog/categories/社区动态",
    "result": {"pageContext":{"allBlogsCount":494,"category":{"name":"社区动态"},"blogs":[{"id":"Blogs_512","title":"AI 时代的向量数据库、关系型数据库与 Serverless 技术丨TiDB Hackathon 2023 随想","tags":["TiDB Serverless","Hackathon"],"category":{"name":"社区动态"},"summary":"AI 时代，向量数据库的身影无处不在。向量数据库到底跟传统的关系型数据库有什么不同，为什么 AI 应用常常需要依赖于向量数据库，基础软件 Serverless 化能带来哪些效率提升？","body":"TiDB Hackathon 2023 刚刚结束，我仔细地审阅了所有的项目。在并未强调项目必须使用人工智能（AI）相关技术的情况下，引人注目的项目几乎一致地都使用了 AI 来构建自己的应用。大规模语言模型（LLM）的问世使得个人开发者能够在短短 5 分钟内为程序赋予推理能力，而这在以往，几乎只有超大型团队才能胜任。从应用开发者的角度来看，AI 时代也已经到来了。\n\n在这些 AI 应用中，向量数据库的身影是无处不在的。尽管这些项目大多仍在使用关系型数据库，但它们似乎不再发挥一个显而易见的作用。关系型数据库究竟还值不值得获得应用开发者们的关注呢？\n\n为了解答清楚这个问题，我们需要了解一下向量数据库到底跟传统的关系型数据库有什么不同。\n\n## 什么是向量数据库\n\n为了搞清楚这个问题，我花了一些时间研究了一下向量数据库。接下来我将用最简单的语言来解释什么是向量数据库。\n\n这个世界上的大多数事情都是多特征的，比如你描述一个人可以用身高、体重、性格、性别、穿衣风格、兴趣爱好等等多种不同类型的维度。通常如果你愿意的话，你可以无限扩展这个维度或者特征去描述一个物体，维度或者特征越多，对于一个物体或者事件的描述就是越准确的。\n\n现在，假如开始用一个维度来表达 Emoji 表情的话，0 代表快乐，1 代表悲伤。从 0 - 1 的数字大小就可以表达对应表情的悲欢程度，如下 x 轴所示：\n\n![一维表达 Emoji](https://img1.pingcap.com/files/2023/09/20230922091918108.png)\n\n但是你会发现，如果只有一个维度来描述情绪 Emoji 的话，这是笼统的，也是不够准确的。例如开心，会有很多种类型的 Emoji 可以表达。那么这个时候我们通常是加入新的维度来更好地描述它。例如我们在这里加入 Y 轴，通过 0 表示黄色，1 表示白色。加入之后表达每个表情在坐标轴上的点变成了 (x, y) 的元组形式。\n\n![Emoji表情-2 个维度](https://img1.pingcap.com/files/2023/09/20230922091929535.png)\n\n聪明的你一定发现了，即使我们加入 Y 轴这个新的描述维度，依然还有 Emoji 我们是没办法区分开的。比如\n\n![Emoji 表情](https://img1.pingcap.com/files/2023/09/20230922091929288.png)\n\n那么怎么办呢？解决这个办法依然很简单，再加一个维度。在坐标系中就是加入 z 轴。我们把新的维度简单设置为是否戴帽子（注意这里每个维度的取值尽可能地简单是为了阐述，不代表真实世界也如此简单）。用 0 表示没戴，1 表示戴了。所以我们现在就得到了一个 (x, y, z) 的三维坐标点来描述一个 Emoji 了。\n\n![Emoji 表情三个维度](https://img1.pingcap.com/files/2023/09/20230922091928889.png)\n\n当然在现实世界中，一个事物的性质不会那么少，所以我们需要通过增加很多个维度来描述它，所以就出现了类似高维数组这样的描述 （0.123, 0.295, 0.358, 0.222 ...）。到这里我们已经非常接近向量数据库中的 “向量” 了，其实向量数据库中存的就是这样的一些数组，用以表示各种各样的数据，包括图片、视频、文字等等。这些事物都是经过我们上述这种转换的方式，把它们变成了一个个高维的数组，然后保存下来。\n\n可能说到这里你还不理解向量数据库有什么作用：为什么我们要把事物变成这样的形式？\n\n简单来讲，这是因为变成向量以后，我们就有办法去量化世界上任意两种事物之间的关联性和相似性了。通过我们刚才的演示，各个维度上越接近的事物，就会在空间中越接近。通过计算两个点之间的距离，就可以判断两者的相似度。\n\n![Emoji表情-多个维度](https://img1.pingcap.com/files/2023/09/20230922091927138.png)\n\n那么如果我们有一个之前从未出现过的一个 Emoji，我们通过上面的方式，可以把这个 Emoji 变成向量（0.01, 1, 0）。\n\n![新 Emoji](https://img1.pingcap.com/files/2023/09/20230922091926676.png)\n\n通过计算跟库中的已经存储的向量，就可以找出来最接近的 Emoji 是\n\n![最近接的 Emoji](https://img1.pingcap.com/files/2023/09/20230922091925824.png)\n\n次之距离接近的就是\n\n![次之接近 Emoji](https://img1.pingcap.com/files/2023/09/20230922091925588.png)\n\n作为佐证，可以看看 [PineCone Query Data](https://docs.pinecone.io/docs/query-data#sending-a-query) 获取数据的例子（Score 可以简单被认为是相似度）：\n\n```java\nindex.query(\n  vector=[0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3],\n  top_k=3,\n  include_values=True\n)\n\n# Returns:\n# {'matches': [{'id': 'C',\n#               'score': -1.76717265e-07,\n#               'values': [0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3]},\n#                   {'id': 'B',\n#                    'score': 0.080000028,\n#                    'values': [0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2]},\n#                   {'id': 'D',\n#                    'score': 0.0800001323,\n#                    'values': [0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4]}],\n#               'namespace': ''}\n```\n\nValues 中就是找回来的向量（在我们这个例子中可以被认为是对应的 Emoji）。这意味着我们可以通过向量化所有的查询条件，找到最 “接近” 我们要求的东西。如果把 Emoji 替换成文本的话，我们就可以实现 “语义” 搜索。如果把 Emoji 替换成图片或者视频的话，就可以实现图片或者视频相似性推荐。\n\n## 为什么 AI 应用常常需要依赖于向量数据库\n\n通过一句话来解释的话就是：“大模型” 能记住的事情有限。\n\n这非常类似于我们的大脑。在交流的过程中，我们不可能把自己所有的知识都在对话中交给对方，通常我们只能通过有限的上下文来做一定的 “推理”。那么在现在的 AI 应用中，推理能力是由 LLM 提供的，而从你的大脑中把需要表达的最相关的上下文找出来。所以类比来看，向量数据库类似于 LLM 的记忆或者知识库。所以完成一个 AI 相关的功能，如果没有向量数据库的帮助，通常 AI 大模型能完成的功能以及准确度就很有限。\n\n沿着这个思路往下看，除了一些不那么精确的模糊匹配以外，其实在现实生活中也存在很多需要非常精确和确定性的搜索/索引。这个就类似于我们通常会把一些重要信息记录在笔记本里面，需要的时候再通过索引把它精确找回来。\n\n所以向量数据库和关系型数据库最大的不同是对于数据的存储方式和索引查询方式。而正是由于关系型数据库当中存在的精确索引，所以它能在毫秒级别获取到对应的信息。对应于业务系统中需要高速访问的例如账号、商品和订单信息等等，目前依然是需要由它来完成。\n\n![向量数据库与关系数据库对比](https://img1.pingcap.com/files/2023/09/20230922091924577.png)\n\n下面以这次 Hackathon 获奖的应用 [Heuristic AI](https://devpost.com/software/cx-8lh7ps) 作为例子给大家展示一下，在一个真实的项目中，分别是怎么使用这两种类型的数据库的。\n\n日常生活中，当我们使用的电子产品出现故障的时候，通常需要翻阅复杂的使用手册才能获取到相关的解决方案，并且需要花费大量的时间学习。这个项目完成了以下事情：\n1.  把所有产品手册导入到向量数据库里面\n2. 把遇到的问题用自然语言描述，通过语义搜索，在向量数据库中找到最相关的上下文\n3. 把上下文打包成 Prompt 发送给 OpenAI，生成对应的解决方案\n\n![项目示例](https://img1.pingcap.com/files/2023/09/20230922091921415.png)\n\n大致的技术实现如下：\n\n![技术实现](https://img1.pingcap.com/files/2023/09/20230922091920696.png)\n\n如果这个软件到此为止了，那基本上也就是一个玩具。通常还需要为系统加入用户认证与管理系统，另外通常在后台还需要加上对业务数据的分析系统，比如多少在线用户使用了产品，使用频率如何等等维度。而这些功能，就需要使用传统的数据库来实现了：\n\n![数据库实现](https://img1.pingcap.com/files/2023/09/20230922091919608.png)\n\n当然作为一个 Hackathon 项目，这个软件其实已经相对比较完整了。但是如果它要进一步产品化，需要考虑以下的方面：\n\n○ 用户数据量暴增，系统的可扩展性和稳定性\n○ 多数据中心和灾难情况下的数据备份和恢复\n\n这些都不酷，甚至有些痛苦，但是这依然是我们需要慎重且认真对待的领域。好在从这次 Hackathon 中，可以肉眼观察到的另一个趋势：Serverless ，在帮助开发者们不断减轻产品化一个应用的技术难度。\n\n## 基础软件 Serverless 化带来的效率提升\n\n可以观察到的：独立开发者在项目开发中发挥的作用日益突出。独立开发者在项目开发中发挥的作用日益突出。相较于过去，不再需要庞大的 3-4 人团队合作，现在的优秀项目往往由 1-2 名开发者，甚至是个别人单独完成。\n\n这一趋势的背后，Serverless 化的浪潮充当了重要的推动力。借助 Serverless，开发者能够专注于业务逻辑，而不必纠结于底层基础设施的细节。这次没有再看到有开发者会利用本地部署实现自己的应用了，前端和业务代码部署使用 Vercel，后端组件，比如 Vector 数据库用 [Qrdrant](https://qdrant.tech/)，或者 [Pinecone](https://www.pinecone.io/)，关系型数据库使用 [TiDB Cloud Serverless](https://bit.ly/3PsYJle)，用上这一套，基本上一个工程师就能完成 Demo 级别的应用了。\n\n这个时代下也并非只有 AI 领域一枝独秀，其他的传统技术，其实也在为开发者们提供越来越方便的使用体验，也在随着浪潮不断递进迭代。\n\n只要关注回到开发者本身，大家都有光明的未来。","date":"2023-09-05","author":"姚维","fillInMethod":"writeDirectly","customUrl":"vector-database-serverless-technology-in-ai-era","file":null,"relatedBlogs":[]},{"id":"Blogs_493","title":"开战在即！与全球伙伴一起打造你的数据应用，TiDB Future App Hackathon 2023 来啦！","tags":["TiDB Hackathon 2023"],"category":{"name":"社区动态"},"summary":"报名即日开启，接受这份来自 TiDB 的邀请，和我们一起在代码世界中创新，体验 Serverless 的魅力，打造专属你的 Data Application！","body":"![Banner.png](https://img1.www.pingcap.com/prod/Banner_e6b70bdbef.png)\n\n2023 TiDB Future App Hackathon 来啦！本届 Hackathon 的主题为：Code, Innovate & Build Amazing Data Applications —— 释放你的创造力、构建突破性的应用、在全球范围内寻找你的队友、体验最新最 in 的 Serverless 技术，更有**总计 $36k 奖金**等你来拿！  \n\n本次大赛需要参赛者基于 TiDB Serverless 进行应用的开发，**TiDB Serverless 专为规模化交易、实时分析和混合工作负载以及流量激增的应用程序而构建，可以自动扩缩容以满足实时需求**。开发人员只需点击几下，就可以部署和配置一个具备完整功能的 Serverless TiDB 数据库。TiDB Serverless 与 MySQL 高度兼容，开发人员可以继续使用他们熟悉的 MySQL 开发框架和工具。  \n\n无论你对数据、人工智能、物联网、跨平台开发或任何软件工程的领域感兴趣，在 2023 TiDB Future App Hackathon 上，你都能充分发挥想象力、创造力，在 TiDB Serverless 上构建可扩展的、强大的、高性能的应用程序都将更加简单！  \n\n报名即日开启，接受这份来自 TiDB 的邀请，和我们一起在代码世界中创新，体验 Serverless 的魅力，打造专属你的 Data Application！  \n\n扫描下方二维码了解活动详情，立即报名活动！  \n\n![活动二维码.png](https://img1.www.pingcap.com/prod/_08d6a2f061.png)\n\n## 赛事支持\n\n![赛事支持.png](https://img1.www.pingcap.com/prod/_a299d58efd.png)\n\n## 参赛指南\n\n### What to Build\n\n在本次 Hackathon 中，你需要使用 TiDB serverless 和任何你喜欢的框架，来构建一个可运行的应用。我们对应用的形式和用途不作限制，充分发挥你的想象力吧！  \n\n一些可能的方向：\n![方向示例.png](https://img1.www.pingcap.com/prod/_61a02f6074.png)\n\n**示例项目**（依次为：OSS Insight、Steam Insight、 Fortune 500 Insight、Hacker News Insight、 S&P 500 Insight）\n\n![OSS Insight.png](https://img1.www.pingcap.com/prod/OSS_Insight_947f479646.png)\n\n![Steam Insight.png](https://img1.www.pingcap.com/prod/Steam_Insight_b84e066598.png)\n\n![Fortune 500 Insight.png](https://img1.www.pingcap.com/prod/Fortune_500_Insight_be8e307e39.png)\n\n![Hacker News Insight.png](https://img1.www.pingcap.com/prod/Hacker_News_Insight_64ef28aef9.png)\n\n![S&P 500 Insight.png](https://img1.www.pingcap.com/prod/S_and_P_500_Insight_5fcfdd1439.png)\n\n如果你暂时没有好的想法，可以通过我们 [Discord](https://discord.gg/PQ9J66rfgW) idea-list 频道来查看小伙伴们提供的 idea 寻找灵感，或者查看给你准备好的 [idea list](https://ask.pingcap.com/t/creative-ideas-list-tidb-future-app-hackathon-2023/495/4)，除此之外，你还可以获得官方准备的 [Development tool](https://ask.pingcap.com/t/sample-applications-development-tools-tidb-future-app-hackathon-2023/560/2)、[public datasets](https://ask.pingcap.com/t/dataset-tidb-future-app-hackathon-2023/497/4)。\n\n以及还有 Hackathon 的传统节目，欢迎来东旭的脑暴直播间（中国标准时间 6月16日 上午 9 点）找找灵感！（扫码即刻报名）\n\n![Hackathon meetup.png](https://img1.www.pingcap.com/prod/Hackathon_meetup_76d5f397ca.png)\n\n不要被这些建议局限住你的思考，我们相信，更多可能性和创造力都在路上！\n\n### How to Start\n\n- 在 [devpost](http://tidbhackathon2023.devpost.com/?utm_source=website-zh&utm_medium=referral&utm_campaign=blog-hackathon-2023) 上报名活动；\n- 自行组队（1 - 4 人），或者在 discord 上寻找你的队友；\n- 在 [TiDB Serverless](https://tidbcloud.com/?utm_source=website-zh&utm_medium=referral&utm_campaign=blog-hackathon-2023) 上创建一个集群；（如果你在应用开发过程中遇到任何挑战，请随时在 [Discord](https://discord.gg/PQ9J66rfgW) 上寻求帮助或参考 [FAQ 部分](https://ask.pingcap.com/t/tidb-serverless-faq-tidb-future-app-hackathon-2023/545/4)的指导。）\n- 构建你的应用程序。\n\n## 赛程介绍\n\n![赛程介绍.jpeg](https://img1.www.pingcap.com/prod/_3ef7fc17b1.jpeg)\n\n### Stage 1  初赛（6/6 - 7/28）\n  \n- [报名](http://tidbhackathon2023.devpost.com/?utm_source=website-zh&utm_medium=referral&utm_campaign=blog-hackathon-2023)、组队\n- 注册 [TiDB Cloud 账户](https://tidbcloud.com/?utm_source=website-zh&utm_medium=referral&utm_campaign=blog-hackathon-2023)并开发应用\n- 提交一段不超过 4 分钟的演示视频，并向评委提供试用参赛的应用程序的途径，可以是接口、账户、网站链接等；同时需要提交参赛项目 GitHub 链接：你的仓库可以是公共的或私人的。如果它是私有的，请在你的测试说明中提供访问权限。记住要包括所有必要的部署文件和测试说明，以方便你的应用程序的测试。（本次大赛面向全球开发者，演示视频需要使用英文进行说明）\n\n评委将通过初赛阶段提交的 demo、程序、代码等评选出 60 只队伍进入决赛阶段，初赛结果将于**8 月 3 日**公布。\n\n### Stage 2 决赛（8/4-8/6）\n\n进入决赛的队伍可以在这三天的时间内优化参赛的程序，并且向最终的大奖发起冲击！  \n\n最终的获奖结果将于**8 月 15 日**公布。\n\n## 评分标准\n\n- 技术实力\n\n包括开发人员对想法的执行情况，以及 TiDB Serverless 功能的利用情况，如 HTAP、可扩展性、实时性和对 AI 能力的运用等。\n\n- 创造力\n\n包括想法的创造性和原创性。\n\n- 用户体验\n\n包括用户体验和视觉设计的水平。\n\n### 部分评委\n\n![评委.png](https://img1.www.pingcap.com/prod/_21c75a9bd8.png)\n\n## 参赛奖励\n\n![参赛奖励.png](https://img1.www.pingcap.com/prod/_753778676e.png)\n\n初赛入围的小伙伴均可获得 TiDB 周边套装一份：  \n\n![TiDB 周边套装.png](https://img1.www.pingcap.com/prod/Ti_DB_68976ac545.png)\n\n准备好体验 TiDB Serverless，开启你的 2023 TiDB Hackathon 了吗？[立即报名](http://tidbhackathon2023.devpost.com/?utm_source=website-zh&utm_medium=referral&utm_campaign=blog-hackathon-2023)","date":"2023-06-07","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"tidb-hackathon-2023-is-coming","file":null,"relatedBlogs":[]},{"id":"Blogs_439","title":"让迁移不再开盲盒，让云也能省钱丨Hackathon 项目背后的故事第一期回顾","tags":["TiDB Hackathon 2022"],"category":{"name":"社区动态"},"summary":"TiDB Hackathon 2022 已经完美收官，我们在赛后策划了一系列「 TiDB Hackathon 2022 非正式会谈」 ——  Hackathon 项目背后的故事 ，邀请大赛评委老师与优秀项目团队一起共话 Hackathon 那些脑洞大开的项目创意。本文为第一期回顾","body":"TiDB Hackathon 2022 已经完美收官，经过两天一夜的 Hacking Time ，共有 16 支队伍获奖，在内核优化、工具、应用、区块链等方向诞生出许多优秀项目。我们在赛后策划了一系列「 TiDB Hackathon 2022 非正式会谈」 ——  Hackathon 项目背后的故事 ，邀请大赛评委老师与优秀项目团队一起共话 Hackathon 那些脑洞大开的项目创意。\n\n第一期迎来的是 Hackathon 应用组项目，主题为“大话 Cloud 成本 & 易用性”。PingCAP 全球社区生态负责人姚维与评委联易融副总裁沈旸、“不上班你养我啊”、“敲代码不喊我是吧”两支赛队队长连线，从企业云上成本优化、TiDB 易用性等角度，进行在线圆桌讨论，解读项目背后的故事及其体现出的应用价值。\n\n## “省钱”的项目——云迹\n\n“不上班你养我啊”这个队名让很多人一看到就瞬间想起了喜剧之王，这个团队的所有小伙伴也希望秉承着“快乐比赛”的理念参与 Hackathon ，甚至连参赛口号都是与之相对应的“省点钱养你”。将他们的队名与口号连接起来，你就能看出“云迹”（项目链接：https://github.com/VelocityLight/yunji ）这个项目的设计初衷。按照队长叶鋆郴的话说，这是一个能直接以“金钱”来衡量价值的项目，他们希望通过搭建一个能够分析云资源成本和使用痕迹的平台，帮助企业省钱。\n\n![云迹.png](https://img1.www.pingcap.com/prod/_90f40dfa41.png)\n\n在创意脑暴时，叶鋆郴和队员们提出了各种 idea，有数据洞察、有直播领域的实时性热点，还有在股市方面的分析预测等，最后大家一致认为成本优化是一个更贴近实际应用场景的应用。这个方向让曾经担任过 CIO 的评委沈旸深有感触。上云之后，云资源的账单永远是一件让 CIO 很头痛的事情。当看到“不上班你养我啊”团队在 Hackathon 答辩 DEMO 中的资源和账单飙升时，他笑言“如果换成以前，血压就直接上来了。”  \n\n沈旸介绍，企业上云虽然能在初期降低入门难度，但实际上在一个公司里，生产系统只占一小部分，大部分系统其实都是给开发测试或者 POC 使用的。而这些系统的运行大部分对 CPU 的占用是比较低的，如果使用率和效率不提升，就会给公司带来大量的资源浪费。举例说，如果一个人工智能训练里调用了 GPU 资源，在训练结束后忘记关了，那这个账单就会像水一样来到你的面前。很多人都会把云计算比喻为自来水一样便利，但如果你不知道哪里漏水了，多出来的水费一样会让你很心疼。  \n\n云迹这个项目正好解决了这个痛点，叶鋆郴认为，“云迹”项目体现出了三方面应用价值：第一，演示了企业在云上部署架构下统一成本分析、关键指标监控告警的问题；第二，考虑到云上账单和资源成本的数据量巨大，统计分析实时查询、告警要求多，项目采用了 TiDB 作为存储和计算引擎，发挥了 TiDB 在 HTAP 应用场景下的价值。比如遇到异常情况下，如果告警不及时，有可能就会带来很大的财产损失，TiDB 的 HTAP 能力正好满足了海量数据场景下的实时性要求；第三，本次 Hackathon 主办方为参赛者提供了一些 TiDB Cloud 和 AWS 的免费额度，在云上为团队搭建应用、部署、开发提供了更好的便捷性。\n\n## 让数据库迁移不再像开盲盒——TiKey\n\n“敲代码不喊我是吧”团队的项目“TiKey”（项目链接：https://github.com/cutecutecat/TiKey ）则解决了企业的另一个痛点——兼容性。姚维分享了一个曾经的痛苦经历：当年在给一些客户项目做 POC 的时候，跑到线上才发现数据库出现各种各样的问题，数据导到一半被迫停止，过程特别痛苦。  \n\n“敲代码不喊我是吧”队长陈俊宇表示，“TiKey”项目会极大节省这个时间，它原理上是一个 MySQL 协议检查器/审计工具，用于在进行 SQL 协议的迁移前，检查不符合 TiDB 规范的协议，并提供部分错误描述。\n\n![TiKey.png](https://img1.www.pingcap.com/prod/Ti_Key_e36d645ec0.png)\n\n其实各种语言都会有自己的检查器，如 Rust 有 clippy，Python 有 autopep8 ，这些检查器会检查你写的一些代码语句中的错误。有时候你写的有些代码并不一定错误，但是可能语法上存在一些问题，比如同样一个语句，它在 MySQL 中能够正常运行，但是放在 TiDB 中可能就不能运行了，TiKey 就是检查不同数据库之间存在兼容性问题的工具，并且还能自动地给出相应的分析和说明，告诉你这个语句哪里除了问题，应该如何解决，或者附上一些链接，告诉你去哪里找到解决方案。它使用了规则预注册模型，规则定义与检查器分离，支持快速拓展新规则，或者随着 TiDB 版本更新对现有规则进行修订。  \n\n以前，当你从 MySQL 迁移到 TiDB 的时候，需要人工检查每一句代码是否有问题，问题出在哪里，整个过程非常像开盲盒，运气好没什么问题，运气不好就可能在一个项目里陷进去几个月出不来。即使是在同一个数据库的不同版本中迁移升级，也会经常遇到新版本的特性和旧版本不兼容。所以很多公司会长期锁定一个版本，即便发布了新版本，也不敢轻易升级。一直等到这个版本已经失去支持，官方不再维护时，才会拉一群人拉通对齐，经过无数次尝试才能将这个迁移工作推进下去。“TiKey”这个项目可以非常显著地节省企业人力的工作时间。  \n\nTiDB 在用户中其实一直都以高度兼容 MySQL 著称，“敲代码不喊我是吧”为什么还会尝试这样一个方向呢？陈俊羽提出其实 TiDB 对 MySQL 的兼容性已经做得相当好，这才让团队能够在 Hackathon 这么短的时间内完成项目，如果兼容性比较差，项目实施中将会有上百条规则需要人为导入检查器。在 Hackthon 短短的几天中，很难将完成度提升到可展示的级别，这个项目在预研时也就很难成立。\n\n## 如何衡量应用组项目价值？——完成度、便捷性、长期规划\n\n在评委沈旸的眼中，能令他打出高分的项目要满足几个标准：第一是项目的完成度。一个项目到应用层，实际上已经是一个从 idea 到落地的过程，最终这个应用是要能直接交付给最终用户使用的。所以，应用的完成度要考虑到用户使用的便捷性，有没有解决用户真实的应用场景问题。第二，需要看该应用对未来的规划。Hackathon 比赛中不管选手投入多少时间，都是一个很短的周期，能完成的功能比较有限。所以作为评委，需要看这个应用有没有一个更长期、更完整的规划，下一步要怎么做？有没有做过市场调研？未来的用户在哪里？  \n\n云迹和 TiKey 在本次 TiDB Hackathon 大赛中在完成度和未来规划都有着非常好的表现，也因此分别收获二等奖 + 最佳人气奖和三等奖+最佳校园奖。两位队长也给未来想参加 TiDB Hackathon 的选手们送上一些 tips，希望帮助更多选手可以打开视角，基于 TiDB 打造出更多具有创意的项目：  \n\n**叶鋆郴**：第一，参加 Hackathon 前期准备非常重要。建议大家可以多花些时间在选题上，选题确认后，再对项目做一些可行性分析，这样我们就能清楚地知道在比赛中每一步要做什么以及能不能在规定时间内实现这些功能点；第二，如果 DEMO 演示中涉及到一些敏感数据或者比较难获取的数据，可以用仿真的方式来做演示。其实大家只要通过仿真场景了解项目的核心功能就可以；第三，要快乐比赛。我们团队每一次比赛都是很欢乐的，获奖和名次其实没那么重要，既然参赛了就要享受比赛，少些顾虑。\n\n**陈俊羽**：第一也是可行性分析。因为 TiDB Hackathon 不允许抢跑，比赛开始前我们还不能写代码。但是在这段时间我们其实可以对项目创意进行技术选型，当这些东西确认好，后面才能在比赛中用非常短的时间将整个原型开发出来。第二，可能有些人一开始并不相信自己能成功参加这样一场比赛。但是没关系，大家都有第一次，只要相信自己，放手去参加一次就会得到很多收获。Hackathon 的意义就是挑战不可能，很多项目都是一边设计一边修改一边实现，在这个过程中你可以学习到很多新的知识，也会认识很多新的朋友，去感受快乐！第三，对于像我一样的学生小伙伴，我建议平时去培养比较好的编码能力，尽可能去参与一些开源社区活动，多学习多交流，构建自信，提升综合能力。\n","date":"2022-11-10","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"the-story-behind-tidb-hackathon-1","file":null,"relatedBlogs":[{"relatedBlog":{"body":"![hackathon 2022 kv.jpeg](https://img1.www.pingcap.com/prod/hackathon_2022_kv_000f450a54.jpeg)\n\n一年一度的 TiDB Hackathon 又来啦！\n\n[TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 主题为「**Possibility at Scale**」，9 月 13 日正式开启，线下决赛将在 2022 年 10 月 22 - 23 日举行。期待与你一起打破传统技术边界，突破固有思维局限，用 TiDB 释放创新的更多可能性。\n\n本届 TiDB Hackathon 将面向更广泛人群，分为**应用组**与 **TiDB 产品组**两大赛道。无论你是应用开发者、数据库开发者、数据库上下游生态从业人员，还是数据库使用者，都可以找到适合自己的方向，一起“玩转” TiDB。\n\nTiDB Hackathon 报名通道于 2022 年 9 月 13 日正式开启，**选手们可以自行组队参赛，通过初赛甄选后，将在现场完成 Coding 及决赛答辩，优胜队伍将获得奖金、技术和资源商的支持**。大赛评委阵容豪华，数据库领域资深专家、社区技术大牛、顶级投资人代表将对项目进行深度点评。此外，还有顶级投资人全程参与评选，让你的实力被更多人看到。\n\n**扫描下图二维码，立即报名参赛**，或前往 [TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 活动页报名。\n\n![报名参赛.jpeg](https://img1.www.pingcap.com/prod/_f7bfacf978.jpeg)\n\n从 2017 年到 2022 年，TiDB Hackathon 不断升级，吸引了全球 1000 + 技术爱好者参与，先后诞生了诸如 UDF 引擎、TiExec、TiMatch 等深受好评的硬核项目，也有 zh.md、TiDB 驾驶舱、pCloud 等新颖有趣的项目。同时，部分优秀项目还在海内外媒体平台获得了多重曝光，借助 TiDB 社区力量为项目提供更多生命力。\n\n在 TiDB Hackathon ，你可以尽情发挥想象力与创造力，全情投入，实现自己的 idea。我们希望你可以永葆对技术的热情与好奇心，在代码的世界中勇敢探索、一往无前。我们在 TiDB Hackathon 2022 等你，期待与你共赴这场技术盛宴！\n\n## 赛事亮点\n\n🌟 **奖金丰厚**\n\n大赛总奖金池高达 35 万元，奖项多达 10+ 个，涵盖各个方向，力求全方位挖掘各参赛项目的价值。\n\n🌟 **各路大神同台竞技**\n\n技术大神齐聚一堂，上演“神仙打架”，场面超燃。高手之间的巅峰对决，精彩纷呈，让人大开眼界。\n\n🌟 **高质量交流**\n\n数据领域知名专家、社区技术大牛担任大赛评委，对项目进行深入点评，还有顶级投资人全程参与评选，你将不止收获硬核的技术反馈，还会获得前瞻性启发。\n\n🌟 **优秀项目专题采访**\n\n大赛结束后，我们将对优秀项目进行专题采访，在海内外技术圈多重曝光，提升优秀项目的知名度，借助 TiDB 社区力量为项目提供更多生命力。\n\n## 丰厚奖金\n\n**奖金池 35 万元，10+ 奖项，20+ 获奖团队**\n\n![丰厚奖金.jpeg](https://img1.www.pingcap.com/prod/_d265519d19.jpeg)\n\n**神秘定制社区周边**\n\n![定制社区周边.jpeg](https://img1.www.pingcap.com/prod/_c6c05c4a61.jpeg)\n\n## 参赛对象\n\n不管你是数据库内核工程师、数据库生态上下游开发者，还是应用开发者，只要你有 idea，都可以报名参赛，一展你的风采！\n\n## 赛道设置\n\n**应用组**\n\n以体现 TiDB 产品价值为主，基于 TiDB 之上实现代码开源的产品、工具、应用等均可。部署方式上，更推荐基于 Cloud 构建 TiDB 相关应用。推荐领域：游戏、电商、金融科技、公益等。\n\n**TiDB 产品组**\n\n为 TiDB 内核产品以及 TiCDC、TiDB Lightning、TiUP 等周边工具的性能、稳定性、易用性或功能等各方面做出提升。\n\n## 赛程安排\n\n- 报名：即日起 - 10 月 17 日，开启报名\n\n- 组队：9 月 17 日，参加「非正式会谈 — 创意脑暴会」，获取项目灵感（详见下方介绍）\n\n- 线上初赛：报名后 -  10 月 17 日，提交 RFC 进入初赛环节\n\n- 名单公布：10 月 19 日，查看决赛入围名单\n\n- 现场 Coding & 决赛：10 月 22 日 - 10 月 23 日，现场 Coding & 决赛答辩\n\n![比赛日程.png](https://img1.www.pingcap.com/prod/_357da0cc3c.png)\n\n## 评委阵容\n\n数据库领域知名专家、社区技术大牛、顶级投资人代表等担当评委，还有顶级投资人全程坐镇，对比赛项目深入点评。\n\n![评委.png](https://img1.www.pingcap.com/prod/_db0a886a7b.png)\n\n<center>（评委按姓名首字母排序）</center>\n\n比赛有输赢，技术无高低。即便最终未能问鼎巅峰，朝着心之所向全力冲刺依旧是一段值得回忆的旅程。秉承不断突破和创造的黑客精神，来一场技术的狂欢盛宴吧。放码过来！\n\n## 创意脑暴会给你灵感\n\n**TiDB Hackathon 2022 非正式会谈 —— 创意脑暴会**来啦，这里有超多 idea，特邀东旭以及资深架构师们在线脑暴，给你超丰富项目灵感。9月17日 本周六 10:30-12:00（GTM+8），线上见～\n\n![创意脑暴.jpeg](https://img1.www.pingcap.com/prod/_a800efa48b.jpeg)\n\n## 合作伙伴\n\n![合作伙伴.png](https://img1.www.pingcap.com/prod/_c6b365d0d3.png)\n\n了解 [TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 更多精彩！\n\n","author":"PingCAP","category":3,"customUrl":"tidb-hackathon-2022-is-coming","fillInMethod":"writeDirectly","id":426,"summary":"一年一度的 TiDB Hackathon 又来啦！TiDB Hackathon 2022 主题为「Possibility at Scale」,9 月 13 日正式开启，线下决赛将在 2022 年 10 月 22 日 23 日举行。","tags":["TiDB Hackathon 2022"],"title":"TiDB Hackathon 2022丨总奖金池超 35 万！邀你唤醒代码世界的更多可能性！"}},{"relatedBlog":{"body":"![banner.jpeg](https://img1.www.pingcap.com/prod/banner_6e96e050b4.jpeg)\n\n一年一度黑客们的狂欢——[TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 报名已开启，万元奖金等你来拿，还有技术专家、顶级投资人全程坐镇，你的实力将被更多人看到。\n\nTiBD Hackathon 2022 ·「Possibility at Scale」，邀请你一起打破传统技术边界，突破固有思维局限，用 TiDB 释放创新的更多可能性。\n\n悄悄说：今年真的不卷，值得一试！\n\n两大赛道，任选：\n\n- 应用组：推荐噢，因为特别奖项更多！\n\n以体现 TiDB 产品价值为主，使用 TiDB 构建代码开源的产品、工具、应用等均可。部署方式上，更推荐基于 Cloud 构建 TiDB 相关应用。常见应用领域：游戏、电商、金融科技、公益等。\n\n- TiDB 产品组：延续传统，保持初心\n\n为 TiDB 内核产品以及 TiCDC、TiDB Lightning、TiUP 等周边工具的性能、稳定性、易用性或功能等各方面做出提升。\n\n扫描下方二维码立即报名参与！\n\n![报名.jpeg](https://img1.www.pingcap.com/prod/_3b43724e2f.jpeg)\n\n听说你想参加 TiDB Hackathon，却没有 idea？\n\n别担心，脑洞达人东旭和他的架构师朋友们在创意脑暴会上分享的项目 idea 都整理好啦，快来看看有没有你感兴趣的~（ps：搭配视频查看 idea 详细介绍，效果更佳哦~） \n\n**创意贡献嘉宾**\n\n黄东旭 PingCAP 联合创始人兼 CTO\n\n姚维 PingCAP 全球社区生态负责人\n\n张兴晔 多点系统架构师\n\nCheng Chen PingCAP Product Manager\n\n[脑暴会视频](https://www.bilibili.com/video/BV1yG411u7N9/)\n\n## 应用组\n\n![应用组.jpeg](https://img1.www.pingcap.com/prod/_e769b14808.jpeg)\n\n今年应用组的决赛参赛项目仅要求是 demo 级别的，例如以下项目示例：\n\n- OSS Insight：https://ossinsight.io/\n\n这是一个基于 TiDB 实现的，数十亿 GitHub events 数据构建的洞察工具。只要你会写 SQL，就可以基于 Docusaurus、Apache ECharts 构建一个强大、酷炫的数据洞察工具。\n\n- TiDB & Snowflake Demo：https://tidb-snowflake-e-commerce-demo.vercel.app/\n\n这是一个基于 TiDB 和 Snowflake 构建的电子商务系统，该系统使用了 TiDB 强大的实时 HTAP 能力和 Snowflake 的离线分析能力，来处理系统中大量的数据。\n\n- Ti-Click：http://ide.ti-click.com/\n\n这是 TiDB Hackathon 2021 的 20 强项目之一，项目通过在线 IDE 的方式，快速搭建基于 TiDB 的 Example App 的开发和在线编译的实验室，可帮助开发者快速学习 TiDB。\n\n- Bookshop\n\n这是一个基于 TiDB 搭建的在线书店应用，你可以通过它来学习如何导入表结构和数据，以及如何基于这些数据来编写 SQL。\n\n[这篇文章](https://docs.pingcap.com/zh/tidb/stable/dev-guide-bookshop-schema-design)也以 Bookshop 应用的数据表结构和数据为基础来编写示例 SQL，为你介绍如何导入该应用的表结构和数据，以及其数据表结构的定义。\n\n- Gitpod\n\n对于 TiDB 初学者，我们基于 Gitpod，提供了一个云原生开发环境的使用帮助，你可以直接从你的浏览器或桌面 IDE 启动一个远程的 TiDB 开发环境，快速体验 TiDB 的能力。我们编写了全新的 TiDB 开发者文档，这份文档可以帮助应用开发者，在最短时间内上手 TiDB。\n\nTiDB 开发者文档：https://docs.pingcap.com/zh/tidb/stable/dev-guide-overview\n\n## TiDB 产品组\n\n![TiDB 产品组.jpeg](https://img1.www.pingcap.com/prod/Ti_DB_77ad779a1c.jpeg)\n\n## 彩蛋组\n\n彩蛋组不可更改 TiDB/TiKV 源码，仅可使用插件方式进行 Hack。\n\n![彩蛋组.jpeg](https://img1.www.pingcap.com/prod/_f6b386df89.jpeg)\n\n希望可以给你一些方向与灵感！更多项目 idea 也可以来 [Hackathon 2022 创意库](https://asktug.com/t/topic/933124)找灵感。\n\n看到这么多 idea，你是否跃跃欲试了呢？\n\n热爱编程，勇于探索，就能参赛\n\n你离万元大奖只有一个报名的距离~\n\n了解 [TiDB Hackathon 2022 ](https://tidb.net/events/hackathon2022)更多详情！","author":"PingCAP","category":3,"customUrl":"hackathon-idea-list-for-reference","fillInMethod":"writeDirectly","id":427,"summary":"一年一度黑客们的狂欢——TiDB Hackathon 2022 报名已开启，万元奖金等你来拿，还有技术专家、顶级投资人全程坐镇，你的实力将被更多人看到。","tags":["TiDB Hackathon 2022"],"title":"Hackathon idea 清单出炉，总有一款适合你"}},{"relatedBlog":{"body":"[TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 正在火热报名中，截止目前已经收到 230+ 位参赛者报名，组队近 60 组。想必各位选手已经摩拳擦掌，开始准备自己项目的 RFC 了。\n\n在等待比赛日的这段时间，**TiDB 社区采访了多位 Hackathon 参赛选手，通过访谈为大家分享一下他们对 Hackathon 的理解和感悟，同时探讨开源给他们的个人生活和工作带来了哪些改变**。当然，作为老选手，也会有极其珍贵的参赛经验分享。已经报名参加本届 Hackathon 的选手或是对 Hackathon 感兴趣的小伙们，赶紧看过来！\n\n今天与大家见面的参赛选手是**目前在南京邮电大学读研三的陆涣冰同学**，其实他的专业方向本来是卫星通信，但内心却十分热爱计算机底层技术，业余时间基本 all in 在开源分布式数据库上。\n\n## 本期嘉宾：陆涣冰\n\n> 涣冰同学与 TiDB Hackathon 的缘分源自研一那年：当时看到比赛的信息后就非常想参加，但苦于自己技术水平不够，同时也没找到人组队，差点错过。幸好当时社区的运营同学给了很多鼓励，并说明个人参赛也是规则允许的，这才被引入了 Hackathon 这条路。之后涣冰就一发不可收拾，研一、研二、研三接连三届都参加了 TiDB Hackathon。\n\n以下为采访记录：\n\n**Q 为什么选择单刷的方式参加 TiDB Hackathon**？  \n\n**陆涣冰**：其实单刷主要是因为自己想做的一些东西，对于很多人而言比较抽象，比较困难。举例来说，我去年做的题目就是用 eBPF 去加速 TiDB 的底层存储路径。这个项目可能需要比较多的底层知识的铺垫，当时问了一圈发现没人对此感兴趣，最终还是自己一个人参赛。其实拿不拿奖无所谓，玩得开心就好。**参加 TiDB Hackathon 帮我整个研究生的三年开了一个头，之后我又参加了各种开源的比赛**，比如阿里的天池数据库大赛、open Euler 高校开发者大赛等等。  \n\n我能开启这条路要感谢两个人。第一个人就是当时的社区运营 yanqing，她对我有某种程度上的知遇之恩，如果没有她我后面的这些经历应该都不存在。第二个人是当时在 P 社实习时的 mentor 施闻轩，他对于我在技术上理解的影响是比较深远。\n\n**Q 最早是在什么时候对编程感兴趣的**？  \n\n**陆涣冰**：我本科的专业是网络工程，研究生的专业是信息网络，乍一听起来好像都是计算机学科的分支。那时候其实走了一段弯路，当时整个人掉进了安全的圈里，觉得黑客好酷，什么病毒、逆向都觉得非常酷。**但是在深入学习了安全一段时间，就感觉做安全好玩归好玩，但是真的要把这个当做职业，心里感觉还是缺了一点什么**。在 2019 年 2 月 1 日，那天是我的生日，所以我印象特别清晰，在跟朋友聊天时，我问自己以后确定要做安全了吗？还是想更深入地写代码？因为当时身边很多做安全的朋友只是敲敲命令行跑跑脚本，感觉中国的安全确实青黄不接，厉害的确实非常厉害，但菜的实在是太菜了。那时候我这方面的技能，不谦虚地讲可以说是炉火纯青了，但是写代码的功底还是一塌糊涂。   \n\n和来自美团、百度的一些圈内朋友聊了聊，他们建议可以考虑一下前端业务应用开发或编译器、数据库、操作系统等更底层的开发。当时也是年少无知，就说要不学个数据库吧。于是从那天就一直学到了今天，然后就发现**一入数据库深似海，这里面的东西实在是太庞大了。不仅要有系统知识，还要涉及编译器的知识，分布式的知识**。伴随着这个学习过程，自己编码的水平也逐渐上来了。  \n \n说实话，身边除了自己，再也找不到第二个人做软件开发或者数据库开发。平时在学校的教研室里基本清一色都是前端开发，这三年来，就我一个人坐电脑前自学了三年。在接触到 PingCAP 时，有一种突然找到组织的感觉。\n\n**Q 开源带来的乐趣或收益是什么**？  \n\n**陆涣冰**：学习数据库的时候其实已经对开源有了一定的认知，基本上 99% 的知识全部来自于开源，无论对操作系统还是对计算机体系的理解，基本都是构建于开源软件之上的。第一次接触 Linux，我发现这不就是我想要的操作系统？**大家都能改、都能用，改完还能 push 进项目里，开放给别人用。某种程度上开源可以汇聚全人类的智慧去做一些事情**。当然开源协作也会有很多问题，比如贡献的代码好不好，有没有漏洞，能不能和别人达成一致协商等等。有些项目写一半甚至不写了，开发者跑了，撂挑子了，这都很常见。包括开源项目的商业化，哪些拿过来可以做出自己的东西，哪些可以二次开发拿去卖，哪些行为是违规的，都需要开源参与者去考虑。  \n\n但那时我还只是开源的使用者，到了读研之后，借由数据库才慢慢把手伸得更远一点，开始把自己的代码贡献给别人。\n\n**Q TiDB Hackathon 与其他比赛在体验上有什么区别**？  \n\n**陆涣冰**：那实在是太多了。**第一还是人**，PingCAP 这边的小助手实在是太热情了，工作做得非常好。我参加了三年，基本上会和每一届的小助手成为朋友。第二点是 Hackathon 的所有项目都构建在 TiDB 之上，**TiDB 有非常多的文档，有对于内核、原理的解读，我认为这点在众多参与过的比赛、项目中可以说是最优秀的**。这些工作大大减少了开发者想深入了解 TiDB 所需要的时间。举个例子，我在参加某个比赛的时候，他们就干巴巴地放出赛题以及代码框架，剩下就全部交给你自己了，非常不容易上手，新手非常难做。而 TiDB 的源码与文档可以帮助开发者在比赛中减少非常多的时间。  \n \n也说说不足，我已经参加了三届，感觉其实有很多 idea 都是前面已经做过的，总会被不断掏出来翻新。建议官方可以把过往的项目整理出来，避免后面的重复。去年有人说 Hackathon 是不是已经没有太多 idea 可以提了，其实我认为随着 TiDB 的发展，加了很多新的 feature 后 TiDB 已经变得越来越复杂，大家原本对于 TiDB 3.0、4.0 的理解放在 6.0 上可能就不适用了，需要再花大精力去做一些有比较有意思的东西。但这可能就需要花很长时间读源码，深入了解 6.0 的设计，这对于外面想参加的人来说就非常困难，所以他们才会说能做的变少了。其实不是变少了，是难度变得太高了，花费的时间成本更高了。\n\n**Q 作为老选手，能不能给新选手分享一下 Hackathon 创意的灵感**？  \n\n**陆涣冰**：其实我有一个想法，有一天我们能把编译器、数据库、操作系统打通，把数据库直接放在与操作系统一样的等级上去。我的所有灵感一直都是围绕这个愿望出发的，**不要为了比赛而想点子，而是为了做出自己理想中的那个数据库，让现在的数据库朝着理想中数据库出发，看看还有什么缺的地方，一步一步实现**。  \n \n我今年的思路其实和东旭之前的想法很相似，TiDB 后端现在存储引擎用的是 target 编码，先前计算机如果出了问题，都可以通过添加一层中间件或者中间层来解决。那我就想能不能添加这样一个中间层，把 TiDB 和 TiKV 解耦，让后面的存储引擎能够无缝切换。这是我今年想做的事情，但是不知道能不能做成功，做成什么样子。  \n \nLinux 内核进入 6.2 版本之后， Rust for Linux 基本上就能稳定了，**当 Rust 进入 Linux 内核之后，能与数据库更深层次的互动**。这个就是我讲的把操作系统与数据库放在同一个 level，其实一直在朝这个目标在走。\n\n**Q 今年是你第三次参加 TiDB Hackathon，你觉得这些年有哪些变化**？  \n\n**陆涣冰**：作为一名底层开发者，**TiDB Hackathon 最吸引我的就是比较硬核的技术，比如 TiDB 先进的存储引擎、高效的性能，它能勾起我们的好奇心，去发掘一下这个数据库到底牛在哪**。  \n\n如果是对于前端开发者而言，TiDB Hackathon 对他们的吸引力就是**借由 TiDB 能去开发一些有意思的应用**，比如说无缝切换，比如更 native 的云原生基础组件，甚至替换 Kubernetes 里的某些功能等等。  \n \n我看到今年的赛制发生了一些变化，比如去年大多数比赛环节都安排在 48 小时里，初赛、决赛答辩，时间安排得满满当当。但今年主办方把初赛提前了，这能让选手们准备得更充分。参加 TiDB Hackathon 的大部分选手都是有工作经验的，或者是有 TiDB 使用经验的。他们对于这个数据库有着非常深的理解，可以借由 Hackathon 的机会把一些 actions 提前给做了。**但是对于外面的学生或者不是太熟悉 TiDB 架构的人而言，比赛周期的延长就非常有意义了**，他们能够有更充足的时间去阅读源码或者阅读文章，加深理解，能把 demo 做得更好一些。我第一届参赛时连 demo 都没有，根本来不及做。   \n\n另外，其实这些年我发现身边做底层开发的小伙伴虽然越来越多，但仍旧是杯水车薪。更多的人还是应用开发者，他们关心如何用数据库，而不是开发数据库，所以应用开发这个赛道的增加就很有意义了。应用开发者可以尽可能发挥，用这个数据库做出一些非常有意思的应用，展现出 TiDB 的更多可能性。\n\n**Q 参赛经验分享**  \n\n**陆涣冰**：想 idea 的时候千万不能闭门造车，要集思广益，收集一下已有的 RFC 或者 AskTUG 论坛里的一些问题，看一看 TiDB 的痛点在哪儿；再从评委的角度去想一想，是不是能第一时间 get 到你的想法。  \n\n我其实还没正式开始写 RFC，我的习惯是先把想法写在纸上，确定好了再腾到电脑上。**写 RFC 首当其冲是要表明你的目的，做这个东西是为了解决什么问题；其次描述一下项目的背景，让评委能明白这个项目的定位是在 TiDB 的哪一个技术分支里面；除此之外，要把图画好，这样才能讲好你的故事**。我第一次 demo 都没做出来，所以答辩的结果也就不尽如人意。第二次答辩确确实实把这个东西做出来了，做得是不是完美其实没有关系，大部分选手时间都一样紧张，关键在于能把你想做的事情、要做的事情、已经做过的事情讲明白就 OK 了。至于什么花里胡哨的画图、图表、效果，都是锦上添花的东西。\n\n关于如何设计 RFC ，可以参考这里：https://asktug.com/t/topic/903770\n\n我从本科到现在，参加了百余场比赛，而且每一场都是单刷。其实参加这些比赛的初衷是想把技术学好，想能为别人再做点什么事情，能做出来一些更实用的东西当然最好，不会太过于关注奖品、名次这些事情，更多还是关注于自己的项目和想法有没有实现。即便没有得到评委的认可，也是自己花时间和精力做出来的，这些写过的代码，对于自己的提升是 100% 是有帮助的。\n\n💡 看过涣冰的经历，你心动了吗？了解 [TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 更多详情，立即报名参加吧！","author":"PingCAP","category":3,"customUrl":"participated-in-hackathon-3-times-alone","fillInMethod":"writeDirectly","id":429,"summary":"在等待比赛日的这段时间，TiDB 社区采访了多维 Hackathon 参赛选手，通过访谈为大家分享一下他们对 Hackathon 的理解和感悟，同时探讨开源给他们的个人生活和工作带来了哪些改变。","tags":["TiDB Hackathon 2022"],"title":"单刷 3 届 Hackathon，朝着理想中的数据库出发丨TiDB Hackathon 选手访谈"}},{"relatedBlog":{"body":"![Possibility at scale.jpeg](https://img1.www.pingcap.com/prod/Possibility_at_scale_9f90da9a4e.jpeg)\n\nTiDB Hackathon 2022 决赛刚好在 1024 程序员节前夜完美收官，48 小时的 Happy Hacking，参赛项目有趣、有料，精彩不断！  \n\n本届大赛主题为「Possibility at Scale」，规模创历史之最，共有 303 名选手报名 ，86 支队伍参赛，有来自微软、蚂蚁集团、字节跳动、网易有道、浪潮、明朝万达、B 站、思科、太极图形等企业的选手，也有来自清华大学、北京邮电大学、华东师范大学、浙江理工大学、新加坡国立大学等高校的学生。选手们围绕着 TiDB 产品组和应用组两大赛道，展开了一场技术的比拼和创意的碰撞。  \n\nHackathon，即“黑客马拉松”，是程序员非常喜闻乐见的赛事活动。它有着自由的形式：Hacker 们聚集在一起，紧密合作，发挥创意，持续编程，实现创想。编程马拉松的精髓在于：一群志同道合的伙伴，在特定的时间内，相聚在一起，去做他们想做的事情——整个编程的过程几乎没有任何限制。  \n\n作为一个已经举办了 5 年的赛事，PingCAP 联合创始人兼 CTO 黄东旭总是焦虑上届已经办得非常成功，这届达不到上届水准怎么办？但当看到选手们的精彩展示后，我们发现随着开发者们对 TiDB 的理解和使用越来越纯熟，Hackathon 的质量也在不断进化。最终，在两天一夜的 Hacking Time 中，有 16 支队伍瓜分了总计 35 万元的奖金，其中有 10 支队伍分获最佳创意奖、公益贡献奖、技术趋势奖、Cloud 应用生态奖、最佳人气奖、最佳校园奖、用户之选奖。\n\n## 硕果累累，项目创意无限\n\n评委老师们认为本届参赛队的很多项目“很有野心”，并已经具备落地的成熟度。例如「图一乐」队通过 “Data Dance” 提供了一个允许你探索、分析、理解数据的在线服务；「12 只喵」队伍让所有人都能通过 TiUP 个人镜像向 TiDB 贡献组件，打造组件市场的雏形；「我垫你们蹲」队通过引入新的索引来实现 TiDB 的协同优化能力的“TiFlash Collocated Optimization”；「cdc-plg」队为 TiCDC 用户提供可扩展插件的“cdc sink plugin”项目；「Canopus」队的“TiDB 计算微服务”项目等等……还有太多项目就不一一列举了，大家可以通过点击该[链接](https://asktug.com/t/topic/994153)了解全部决赛答辩项目。  \n\n由北京、上海、广州、成都、新加坡多城分布式联动的决赛答辩 & Demo Show 从下午 13:00 一直持续到深夜 20:30。虽然决赛时长将近 8 个小时，但是大家越看越兴奋。平时含蓄内敛的技术大佬们一旦介绍起自己的产品，就变身为滔滔不绝的演说家。\n\n最终，经过紧张评选，评委团共评出了 TiDB 产品组和应用的一、二、三等奖和最佳创意奖、公益贡献奖、技术趋势奖、Cloud 应用生态奖、最佳人气奖、最佳校园奖、用户之选奖。由于奖项角逐太激烈，有很多优秀项目遗憾落选，以下是全部获奖名单：\n\n![获奖名单.png](https://img1.www.pingcap.com/prod/_9c72ac9180.png)\n\n### 加冕时刻\n\n![产品组一等奖.png](https://img1.www.pingcap.com/prod/_83934100c4.png)\n<center>TiDB 产品组一等奖获奖团队</center>\n\n![应用组一等奖.png](https://img1.www.pingcap.com/prod/_aa35b79b2c.png)\n<center>应用组一等奖获奖团队</center>\n\n![产品组二等奖.png](https://img1.www.pingcap.com/prod/_dad30e1958.png)\n<center>TiDB 产品组二等奖获奖团队</center>\n\n![应用组二等奖.png](https://img1.www.pingcap.com/prod/_849b963110.png)\n<center>应用组二等奖获奖团队</center>\n\n![产品组三等奖.png](https://img1.www.pingcap.com/prod/_f80f9b1f99.png)\n<center>TiDB 产品组三等奖获奖团队</center>\n\n![产品组三等奖-2.png](https://img1.www.pingcap.com/prod/2_4e2d2b6231.png)\n<center>TiDB 产品组三等奖获奖团队</center>\n\n![应用组三等奖-1.png](https://img1.www.pingcap.com/prod/1_d659502042.png)\n<center>应用组三等奖获奖团队</center>\n\n![产品组最佳校园奖获奖团队.png](https://img1.www.pingcap.com/prod/_0410b64f46.png)\n<center>TiDB 产品组最佳校园奖获奖团队</center>\n\n![应用组最佳人气奖获奖团队.png](https://img1.www.pingcap.com/prod/_b564cf3f38.png)\n<center>应用组最佳人气奖获奖团队</center>\n\n![产品组最佳人气奖.png](https://img1.www.pingcap.com/prod/_b993c9aab3.png)\n<center>TiDB 产品组最佳人气奖</center>\n\n![应用组一等奖.png](https://img1.www.pingcap.com/prod/_aa35b79b2c.png)\n<center>应用组用户之选奖获奖团队</center>\n\n本届参赛项目再一次打开了我们对于 TiDB 想象力的界限。极客们丰富的想象力，会让你大开眼界，重拾对技术探索的激情。\nDemo Show 全程视频即将上线 b 站 [TiDB_Robot](https://space.bilibili.com/86485707/) 账号，敬请期待！\n\n特别感谢 PingCAP 数据平台产品负责人高斌、爱奇艺数据库服务负责人郭磊涛、PingCAP 联合创始人兼 CTO  黄东旭、PingCAP Outbound PM 黄潇、TiDB Committer, Seaweedfs Contributor 李雨来、PingCAP 资深开发工程师刘聪、小米数据库工程师，TiDB Committer 刘子东、Kyligence 技术合伙人，Apache Kylin 社区 PMC 成员马洪宾、联易融副总裁沈旸、TiDB Cloud Ecosystem 研发负责人孙晓光、PingCAP 研发副总裁唐刘、GGV 纪源资本投资人王笛、PingCAP SQL 研发负责人王聪、华创资本管理合伙人吴海燕、积梦智能 CEO，GoCN 社区发起人谢孟军、PingCAP DM 研发负责人徐成选、PingCAP 产研顾问张东晖、 Morpheuslabs CEO Chuang Pei-Han 等老师认真负责的评审。  \n\n赛后，我们还将采访优秀项目赛队，为大家深入介绍他们的项目设计思路、实现过程以及未来工作方向，希望带给大家一些启发。敬请期待！  \n\n最后，感谢华创资本、云启资本、GGV、初心资本、AWS、GCP、伊克罗德等赞助商和合作伙伴对赛事的大力支持，也感谢志愿者们的奉献！TiDB Hackathon 2023 ，我们再见！  \n\n![赞助商.png](https://img1.www.pingcap.com/prod/_b008ab31d6.png)\n\n","author":"PingCAP","category":3,"customUrl":"hardcore-ideas-in-tidb-hackathon-2022","fillInMethod":"writeDirectly","id":436,"summary":"TiDB Hackathon 2022 决赛刚好在 1024 程序员节前夜完美收官，48 小时的 Happy Hacking，参赛项目有趣、有料，精彩不断！","tags":["TiDB Hackathon 2022"],"title":"鏖战 48 小时，TiDB Hackathon 都诞生了哪些硬核创意？"}}]},{"id":"Blogs_436","title":"鏖战 48 小时，TiDB Hackathon 都诞生了哪些硬核创意？","tags":["TiDB Hackathon 2022"],"category":{"name":"社区动态"},"summary":"TiDB Hackathon 2022 决赛刚好在 1024 程序员节前夜完美收官，48 小时的 Happy Hacking，参赛项目有趣、有料，精彩不断！","body":"![Possibility at scale.jpeg](https://img1.www.pingcap.com/prod/Possibility_at_scale_9f90da9a4e.jpeg)\n\nTiDB Hackathon 2022 决赛刚好在 1024 程序员节前夜完美收官，48 小时的 Happy Hacking，参赛项目有趣、有料，精彩不断！  \n\n本届大赛主题为「Possibility at Scale」，规模创历史之最，共有 303 名选手报名 ，86 支队伍参赛，有来自微软、蚂蚁集团、字节跳动、网易有道、浪潮、明朝万达、B 站、思科、太极图形等企业的选手，也有来自清华大学、北京邮电大学、华东师范大学、浙江理工大学、新加坡国立大学等高校的学生。选手们围绕着 TiDB 产品组和应用组两大赛道，展开了一场技术的比拼和创意的碰撞。  \n\nHackathon，即“黑客马拉松”，是程序员非常喜闻乐见的赛事活动。它有着自由的形式：Hacker 们聚集在一起，紧密合作，发挥创意，持续编程，实现创想。编程马拉松的精髓在于：一群志同道合的伙伴，在特定的时间内，相聚在一起，去做他们想做的事情——整个编程的过程几乎没有任何限制。  \n\n作为一个已经举办了 5 年的赛事，PingCAP 联合创始人兼 CTO 黄东旭总是焦虑上届已经办得非常成功，这届达不到上届水准怎么办？但当看到选手们的精彩展示后，我们发现随着开发者们对 TiDB 的理解和使用越来越纯熟，Hackathon 的质量也在不断进化。最终，在两天一夜的 Hacking Time 中，有 16 支队伍瓜分了总计 35 万元的奖金，其中有 10 支队伍分获最佳创意奖、公益贡献奖、技术趋势奖、Cloud 应用生态奖、最佳人气奖、最佳校园奖、用户之选奖。\n\n## 硕果累累，项目创意无限\n\n评委老师们认为本届参赛队的很多项目“很有野心”，并已经具备落地的成熟度。例如「图一乐」队通过 “Data Dance” 提供了一个允许你探索、分析、理解数据的在线服务；「12 只喵」队伍让所有人都能通过 TiUP 个人镜像向 TiDB 贡献组件，打造组件市场的雏形；「我垫你们蹲」队通过引入新的索引来实现 TiDB 的协同优化能力的“TiFlash Collocated Optimization”；「cdc-plg」队为 TiCDC 用户提供可扩展插件的“cdc sink plugin”项目；「Canopus」队的“TiDB 计算微服务”项目等等……还有太多项目就不一一列举了，大家可以通过点击该[链接](https://asktug.com/t/topic/994153)了解全部决赛答辩项目。  \n\n由北京、上海、广州、成都、新加坡多城分布式联动的决赛答辩 & Demo Show 从下午 13:00 一直持续到深夜 20:30。虽然决赛时长将近 8 个小时，但是大家越看越兴奋。平时含蓄内敛的技术大佬们一旦介绍起自己的产品，就变身为滔滔不绝的演说家。\n\n最终，经过紧张评选，评委团共评出了 TiDB 产品组和应用的一、二、三等奖和最佳创意奖、公益贡献奖、技术趋势奖、Cloud 应用生态奖、最佳人气奖、最佳校园奖、用户之选奖。由于奖项角逐太激烈，有很多优秀项目遗憾落选，以下是全部获奖名单：\n\n![获奖名单.png](https://img1.www.pingcap.com/prod/_9c72ac9180.png)\n\n### 加冕时刻\n\n![产品组一等奖.png](https://img1.www.pingcap.com/prod/_83934100c4.png)\n<center>TiDB 产品组一等奖获奖团队</center>\n\n![应用组一等奖.png](https://img1.www.pingcap.com/prod/_aa35b79b2c.png)\n<center>应用组一等奖获奖团队</center>\n\n![产品组二等奖.png](https://img1.www.pingcap.com/prod/_dad30e1958.png)\n<center>TiDB 产品组二等奖获奖团队</center>\n\n![应用组二等奖.png](https://img1.www.pingcap.com/prod/_849b963110.png)\n<center>应用组二等奖获奖团队</center>\n\n![产品组三等奖.png](https://img1.www.pingcap.com/prod/_f80f9b1f99.png)\n<center>TiDB 产品组三等奖获奖团队</center>\n\n![产品组三等奖-2.png](https://img1.www.pingcap.com/prod/2_4e2d2b6231.png)\n<center>TiDB 产品组三等奖获奖团队</center>\n\n![应用组三等奖-1.png](https://img1.www.pingcap.com/prod/1_d659502042.png)\n<center>应用组三等奖获奖团队</center>\n\n![产品组最佳校园奖获奖团队.png](https://img1.www.pingcap.com/prod/_0410b64f46.png)\n<center>TiDB 产品组最佳校园奖获奖团队</center>\n\n![应用组最佳人气奖获奖团队.png](https://img1.www.pingcap.com/prod/_b564cf3f38.png)\n<center>应用组最佳人气奖获奖团队</center>\n\n![产品组最佳人气奖.png](https://img1.www.pingcap.com/prod/_b993c9aab3.png)\n<center>TiDB 产品组最佳人气奖</center>\n\n![应用组一等奖.png](https://img1.www.pingcap.com/prod/_aa35b79b2c.png)\n<center>应用组用户之选奖获奖团队</center>\n\n本届参赛项目再一次打开了我们对于 TiDB 想象力的界限。极客们丰富的想象力，会让你大开眼界，重拾对技术探索的激情。\nDemo Show 全程视频即将上线 b 站 [TiDB_Robot](https://space.bilibili.com/86485707/) 账号，敬请期待！\n\n特别感谢 PingCAP 数据平台产品负责人高斌、爱奇艺数据库服务负责人郭磊涛、PingCAP 联合创始人兼 CTO  黄东旭、PingCAP Outbound PM 黄潇、TiDB Committer, Seaweedfs Contributor 李雨来、PingCAP 资深开发工程师刘聪、小米数据库工程师，TiDB Committer 刘子东、Kyligence 技术合伙人，Apache Kylin 社区 PMC 成员马洪宾、联易融副总裁沈旸、TiDB Cloud Ecosystem 研发负责人孙晓光、PingCAP 研发副总裁唐刘、GGV 纪源资本投资人王笛、PingCAP SQL 研发负责人王聪、华创资本管理合伙人吴海燕、积梦智能 CEO，GoCN 社区发起人谢孟军、PingCAP DM 研发负责人徐成选、PingCAP 产研顾问张东晖、 Morpheuslabs CEO Chuang Pei-Han 等老师认真负责的评审。  \n\n赛后，我们还将采访优秀项目赛队，为大家深入介绍他们的项目设计思路、实现过程以及未来工作方向，希望带给大家一些启发。敬请期待！  \n\n最后，感谢华创资本、云启资本、GGV、初心资本、AWS、GCP、伊克罗德等赞助商和合作伙伴对赛事的大力支持，也感谢志愿者们的奉献！TiDB Hackathon 2023 ，我们再见！  \n\n![赞助商.png](https://img1.www.pingcap.com/prod/_b008ab31d6.png)\n\n","date":"2022-10-24","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"hardcore-ideas-in-tidb-hackathon-2022","file":null,"relatedBlogs":[{"relatedBlog":{"body":"![hackathon 2022 kv.jpeg](https://img1.www.pingcap.com/prod/hackathon_2022_kv_000f450a54.jpeg)\n\n一年一度的 TiDB Hackathon 又来啦！\n\n[TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 主题为「**Possibility at Scale**」，9 月 13 日正式开启，线下决赛将在 2022 年 10 月 22 - 23 日举行。期待与你一起打破传统技术边界，突破固有思维局限，用 TiDB 释放创新的更多可能性。\n\n本届 TiDB Hackathon 将面向更广泛人群，分为**应用组**与 **TiDB 产品组**两大赛道。无论你是应用开发者、数据库开发者、数据库上下游生态从业人员，还是数据库使用者，都可以找到适合自己的方向，一起“玩转” TiDB。\n\nTiDB Hackathon 报名通道于 2022 年 9 月 13 日正式开启，**选手们可以自行组队参赛，通过初赛甄选后，将在现场完成 Coding 及决赛答辩，优胜队伍将获得奖金、技术和资源商的支持**。大赛评委阵容豪华，数据库领域资深专家、社区技术大牛、顶级投资人代表将对项目进行深度点评。此外，还有顶级投资人全程参与评选，让你的实力被更多人看到。\n\n**扫描下图二维码，立即报名参赛**，或前往 [TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 活动页报名。\n\n![报名参赛.jpeg](https://img1.www.pingcap.com/prod/_f7bfacf978.jpeg)\n\n从 2017 年到 2022 年，TiDB Hackathon 不断升级，吸引了全球 1000 + 技术爱好者参与，先后诞生了诸如 UDF 引擎、TiExec、TiMatch 等深受好评的硬核项目，也有 zh.md、TiDB 驾驶舱、pCloud 等新颖有趣的项目。同时，部分优秀项目还在海内外媒体平台获得了多重曝光，借助 TiDB 社区力量为项目提供更多生命力。\n\n在 TiDB Hackathon ，你可以尽情发挥想象力与创造力，全情投入，实现自己的 idea。我们希望你可以永葆对技术的热情与好奇心，在代码的世界中勇敢探索、一往无前。我们在 TiDB Hackathon 2022 等你，期待与你共赴这场技术盛宴！\n\n## 赛事亮点\n\n🌟 **奖金丰厚**\n\n大赛总奖金池高达 35 万元，奖项多达 10+ 个，涵盖各个方向，力求全方位挖掘各参赛项目的价值。\n\n🌟 **各路大神同台竞技**\n\n技术大神齐聚一堂，上演“神仙打架”，场面超燃。高手之间的巅峰对决，精彩纷呈，让人大开眼界。\n\n🌟 **高质量交流**\n\n数据领域知名专家、社区技术大牛担任大赛评委，对项目进行深入点评，还有顶级投资人全程参与评选，你将不止收获硬核的技术反馈，还会获得前瞻性启发。\n\n🌟 **优秀项目专题采访**\n\n大赛结束后，我们将对优秀项目进行专题采访，在海内外技术圈多重曝光，提升优秀项目的知名度，借助 TiDB 社区力量为项目提供更多生命力。\n\n## 丰厚奖金\n\n**奖金池 35 万元，10+ 奖项，20+ 获奖团队**\n\n![丰厚奖金.jpeg](https://img1.www.pingcap.com/prod/_d265519d19.jpeg)\n\n**神秘定制社区周边**\n\n![定制社区周边.jpeg](https://img1.www.pingcap.com/prod/_c6c05c4a61.jpeg)\n\n## 参赛对象\n\n不管你是数据库内核工程师、数据库生态上下游开发者，还是应用开发者，只要你有 idea，都可以报名参赛，一展你的风采！\n\n## 赛道设置\n\n**应用组**\n\n以体现 TiDB 产品价值为主，基于 TiDB 之上实现代码开源的产品、工具、应用等均可。部署方式上，更推荐基于 Cloud 构建 TiDB 相关应用。推荐领域：游戏、电商、金融科技、公益等。\n\n**TiDB 产品组**\n\n为 TiDB 内核产品以及 TiCDC、TiDB Lightning、TiUP 等周边工具的性能、稳定性、易用性或功能等各方面做出提升。\n\n## 赛程安排\n\n- 报名：即日起 - 10 月 17 日，开启报名\n\n- 组队：9 月 17 日，参加「非正式会谈 — 创意脑暴会」，获取项目灵感（详见下方介绍）\n\n- 线上初赛：报名后 -  10 月 17 日，提交 RFC 进入初赛环节\n\n- 名单公布：10 月 19 日，查看决赛入围名单\n\n- 现场 Coding & 决赛：10 月 22 日 - 10 月 23 日，现场 Coding & 决赛答辩\n\n![比赛日程.png](https://img1.www.pingcap.com/prod/_357da0cc3c.png)\n\n## 评委阵容\n\n数据库领域知名专家、社区技术大牛、顶级投资人代表等担当评委，还有顶级投资人全程坐镇，对比赛项目深入点评。\n\n![评委.png](https://img1.www.pingcap.com/prod/_db0a886a7b.png)\n\n<center>（评委按姓名首字母排序）</center>\n\n比赛有输赢，技术无高低。即便最终未能问鼎巅峰，朝着心之所向全力冲刺依旧是一段值得回忆的旅程。秉承不断突破和创造的黑客精神，来一场技术的狂欢盛宴吧。放码过来！\n\n## 创意脑暴会给你灵感\n\n**TiDB Hackathon 2022 非正式会谈 —— 创意脑暴会**来啦，这里有超多 idea，特邀东旭以及资深架构师们在线脑暴，给你超丰富项目灵感。9月17日 本周六 10:30-12:00（GTM+8），线上见～\n\n![创意脑暴.jpeg](https://img1.www.pingcap.com/prod/_a800efa48b.jpeg)\n\n## 合作伙伴\n\n![合作伙伴.png](https://img1.www.pingcap.com/prod/_c6b365d0d3.png)\n\n了解 [TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 更多精彩！\n\n","author":"PingCAP","category":3,"customUrl":"tidb-hackathon-2022-is-coming","fillInMethod":"writeDirectly","id":426,"summary":"一年一度的 TiDB Hackathon 又来啦！TiDB Hackathon 2022 主题为「Possibility at Scale」,9 月 13 日正式开启，线下决赛将在 2022 年 10 月 22 日 23 日举行。","tags":["TiDB Hackathon 2022"],"title":"TiDB Hackathon 2022丨总奖金池超 35 万！邀你唤醒代码世界的更多可能性！"}},{"relatedBlog":{"body":"![banner.jpeg](https://img1.www.pingcap.com/prod/banner_6e96e050b4.jpeg)\n\n一年一度黑客们的狂欢——[TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 报名已开启，万元奖金等你来拿，还有技术专家、顶级投资人全程坐镇，你的实力将被更多人看到。\n\nTiBD Hackathon 2022 ·「Possibility at Scale」，邀请你一起打破传统技术边界，突破固有思维局限，用 TiDB 释放创新的更多可能性。\n\n悄悄说：今年真的不卷，值得一试！\n\n两大赛道，任选：\n\n- 应用组：推荐噢，因为特别奖项更多！\n\n以体现 TiDB 产品价值为主，使用 TiDB 构建代码开源的产品、工具、应用等均可。部署方式上，更推荐基于 Cloud 构建 TiDB 相关应用。常见应用领域：游戏、电商、金融科技、公益等。\n\n- TiDB 产品组：延续传统，保持初心\n\n为 TiDB 内核产品以及 TiCDC、TiDB Lightning、TiUP 等周边工具的性能、稳定性、易用性或功能等各方面做出提升。\n\n扫描下方二维码立即报名参与！\n\n![报名.jpeg](https://img1.www.pingcap.com/prod/_3b43724e2f.jpeg)\n\n听说你想参加 TiDB Hackathon，却没有 idea？\n\n别担心，脑洞达人东旭和他的架构师朋友们在创意脑暴会上分享的项目 idea 都整理好啦，快来看看有没有你感兴趣的~（ps：搭配视频查看 idea 详细介绍，效果更佳哦~） \n\n**创意贡献嘉宾**\n\n黄东旭 PingCAP 联合创始人兼 CTO\n\n姚维 PingCAP 全球社区生态负责人\n\n张兴晔 多点系统架构师\n\nCheng Chen PingCAP Product Manager\n\n[脑暴会视频](https://www.bilibili.com/video/BV1yG411u7N9/)\n\n## 应用组\n\n![应用组.jpeg](https://img1.www.pingcap.com/prod/_e769b14808.jpeg)\n\n今年应用组的决赛参赛项目仅要求是 demo 级别的，例如以下项目示例：\n\n- OSS Insight：https://ossinsight.io/\n\n这是一个基于 TiDB 实现的，数十亿 GitHub events 数据构建的洞察工具。只要你会写 SQL，就可以基于 Docusaurus、Apache ECharts 构建一个强大、酷炫的数据洞察工具。\n\n- TiDB & Snowflake Demo：https://tidb-snowflake-e-commerce-demo.vercel.app/\n\n这是一个基于 TiDB 和 Snowflake 构建的电子商务系统，该系统使用了 TiDB 强大的实时 HTAP 能力和 Snowflake 的离线分析能力，来处理系统中大量的数据。\n\n- Ti-Click：http://ide.ti-click.com/\n\n这是 TiDB Hackathon 2021 的 20 强项目之一，项目通过在线 IDE 的方式，快速搭建基于 TiDB 的 Example App 的开发和在线编译的实验室，可帮助开发者快速学习 TiDB。\n\n- Bookshop\n\n这是一个基于 TiDB 搭建的在线书店应用，你可以通过它来学习如何导入表结构和数据，以及如何基于这些数据来编写 SQL。\n\n[这篇文章](https://docs.pingcap.com/zh/tidb/stable/dev-guide-bookshop-schema-design)也以 Bookshop 应用的数据表结构和数据为基础来编写示例 SQL，为你介绍如何导入该应用的表结构和数据，以及其数据表结构的定义。\n\n- Gitpod\n\n对于 TiDB 初学者，我们基于 Gitpod，提供了一个云原生开发环境的使用帮助，你可以直接从你的浏览器或桌面 IDE 启动一个远程的 TiDB 开发环境，快速体验 TiDB 的能力。我们编写了全新的 TiDB 开发者文档，这份文档可以帮助应用开发者，在最短时间内上手 TiDB。\n\nTiDB 开发者文档：https://docs.pingcap.com/zh/tidb/stable/dev-guide-overview\n\n## TiDB 产品组\n\n![TiDB 产品组.jpeg](https://img1.www.pingcap.com/prod/Ti_DB_77ad779a1c.jpeg)\n\n## 彩蛋组\n\n彩蛋组不可更改 TiDB/TiKV 源码，仅可使用插件方式进行 Hack。\n\n![彩蛋组.jpeg](https://img1.www.pingcap.com/prod/_f6b386df89.jpeg)\n\n希望可以给你一些方向与灵感！更多项目 idea 也可以来 [Hackathon 2022 创意库](https://asktug.com/t/topic/933124)找灵感。\n\n看到这么多 idea，你是否跃跃欲试了呢？\n\n热爱编程，勇于探索，就能参赛\n\n你离万元大奖只有一个报名的距离~\n\n了解 [TiDB Hackathon 2022 ](https://tidb.net/events/hackathon2022)更多详情！","author":"PingCAP","category":3,"customUrl":"hackathon-idea-list-for-reference","fillInMethod":"writeDirectly","id":427,"summary":"一年一度黑客们的狂欢——TiDB Hackathon 2022 报名已开启，万元奖金等你来拿，还有技术专家、顶级投资人全程坐镇，你的实力将被更多人看到。","tags":["TiDB Hackathon 2022"],"title":"Hackathon idea 清单出炉，总有一款适合你"}},{"relatedBlog":{"body":"自 2022 年 9 月 13 日开放报名以来，TiDB Hackathon 2022 共吸引了 303 人报名参赛，由此诞生了 86 支队伍，评委组从应用性/实用性、创新性、完成度、展示度四个维度对大家提交的 RFC 严格筛选，有 62 支队伍成功入围决赛：\n\n![应用组入围.jpeg](https://img1.www.pingcap.com/prod/_c69487e38f.jpeg)\n\n![产品组入围.jpeg](https://img1.www.pingcap.com/prod/_0bf299375b.jpeg)\n\n恭喜以上队伍晋级决赛！\n\n**温馨提示**：决赛入围名单公示之后（即刻起），大家就可以开始准备代码开发。决赛现场评委会严格审查参赛选手的作品是否符合“第一行代码提交时间需在初赛结果公示后”这一规则。\n\n决赛将于 10 月 22 日至 10 月 23 日在上海、北京、广州、成都、新加坡等地的 PingCAP 公司举行，请入围选手 10 月 22 日上午 9:00-10:00 到达决赛现场，签到并领取参赛礼品，决赛详细流程参见[参赛须知](https://asktug.com/t/topic/994153)。其他提交 RFC 的赛队也将获得本次活动的电子参赛证书（将发放给到队长），也欢迎大家线上围观决赛，并参与最佳人气项目的投票，参与投票的小伙伴还有机会抽取礼品哟！\n\n![参赛证书.png](https://img1.www.pingcap.com/prod/_95121197ef.png)\n<center>参赛证书</center>\n\n10 月 22 日上午 10:00 至 10 月 23 日中午 12:00 选手们将在决赛现场 hack，10 月 23 日 13:00 正式开始现场答辩。\n\n届时，小伙伴也能线上围观这场技术盛宴。两个赛道分别在不同平台同时直播，PingCAP 微信视频号将直播 TiDB 产品组的答辩赛况、B 站 TiDB_Robot 账号将直播应用组的答辩赛况，大家可以合理安排时间，优先选择自己更感兴趣的赛道观看直播哟！\n\n## 最佳人气奖\n\n最佳人气奖投票通道已经开启，欢迎 pick 你中意的团队！票数最高的团队将获得最佳人气奖。\n\n投票用户也可参与抽奖，将在投票用户中抽取 5 位，每人送出“TiDB 社区限定挎包”一只。\n\n![限定挎包.jpeg](https://img1.www.pingcap.com/prod/_58590dbb76.jpeg)\n\n投票时间：即时起 - 10 月 23 日答辩结束\n\n投票规则：应用组与 TiBD 产品组 分别投票，每人每个赛道一票\n\n投票方式：扫码即可参与投票\n\n![参与投票.png](https://img1.www.pingcap.com/prod/_3bfdb338a5.png)\n\n## 现场精彩看点\n\n### 项目值得期待\n\n本届参赛项目再一次打开了我们对于 TiDB 想象力的界限。极客们丰富的想象力，会让你大开眼界，重拾对技术探索的激情。先剧透几个有趣的项目给大家～\n\n#### 应用组\n\n**团队名称：Ti 可立刻**\n\n- 项目名称：Ti-Click++\n- 项目介绍：通过 Online IDE 的方式，可以让用户以最简便的方式部署 Sample App。在去年的 TiDB Hackathon 中，这个项目就收获了评委和观众的一致赞赏，并最终晋级 20 强。今年的改进版 Ti-Click++ 将使用 gitpod 的云服务，一次性解决 Eclipse Che 运维难和资源消耗问题。此外将统一业务模型，使用 Real World 的模板进行改造，让用户只需要理解一种业务，但是可以同时理解多种语言链接和使用 TiDB 的方案。\n- 项目链接：https://github.com/ti-click/pingcap-hackathon-2022\n\n**团队名称：cloud naive**\n\n- 项目名称：My Life\n- 项目介绍：My Life 项目希望能记录我们的生活轨迹，存储到 TiDB 中，最终以各种方式展现。项目将基于低代码技术去实现，通过 TiDB Cloud 集成低代码产品 zapier/n8n。\n- 项目链接：https://gist.github.com/shiyuhang0/ae6d9deab4c8e1708b80bea1de9df279\n\n![cloud native.png](https://img1.www.pingcap.com/prod/cloud_native_ff91c09191.png)\n\n**团队名称：不上班你养我啊**\n\n- 项目名称：云迹\n- 项目介绍：成本优化不仅对于公司有着重要意义，也是每个云上开发人员都需要具备的 sense。本项目终极目的是解决企业在云上部署架构下统一成本分析、关键指标监控告警的问题。因考虑到数据量巨大，统计分析实时查询、告警要求多，我们采用 HTAP 数据库的 TiDB 作为存储和计算引擎，发挥 TiDB 在应用场景下的价值。期待可以通过云迹，节约你的金钱亿点点！\n- 项目链接：https://gist.github.com/VelocityLight/ccb4c50e569b1ee733f23a2bb97e8439\n\n![不上班.png](https://img1.www.pingcap.com/prod/_a048f90102.png)\n\n**团队名称：KubeBrain**\n\n- 项目名称：KubeBrain\n- 项目介绍：当前 Kubernetes 仅支持 etcd 作为元信息存储系统，因此部署 Kubernetes 集群总是需要额外的维护一套 etcd 集群，etcd 集群并不支持水平扩容，随着数据量和读写请求量的增长，容易达到瓶颈。我们实现了轻量级 Kubernetes 元信息存储项目 KubeBrain 对存储引擎 API 进行抽象，希望可以通过适配不同的分布式存储系统，从而可以充分利用已有的存储系统作为基础设施来部署 Kubernetes 集群，支持一定程度的元信息存储的水平扩容，打通 Kubernetes 和其他存储系统之间的壁垒。\n- 项目链接：https://gist.github.com/divanodestiny/fd4f957cdc3a099414e7a93459168958\n\n![KubeBrain.png](https://img1.www.pingcap.com/prod/Kube_Brain_4e3cea8e08.png)\n\n**团队名称：1' or '1' = '1**\n\n- 项目名称：TiSQLi\n- 项目介绍：通过 pincap/tidb/parser 对 SQL 对解析能力，对于 Web 接口潜在的 SQL 注入进行检测、拦截和防范。可进一步扩展用于：片段 SQL 语句的注入检测，如 WAF 等网关设备，或者应用内的前置过滤器；完整 SQL 语句的注入检测，如数据库内置的 SQL 检测，或者应用内的数据库中间件。\n- 项目链接：https://gist.github.com/flily/c1009c65e08eaed28e9f39f1d371cea7\n\n#### TiDB 产品组\n\n**团队名称：热点清零**\n\n- 项目名称：Fearless Write Hotspot\n\n- 项目介绍：在分布式系统中，部分热点节点会承载大量用户的读写请求，而单个机器的负载往往是有限的；在单节点上，部分热点线程会承载大量的计算任务，而单核的性能往往也是有限的。整体来看，热点问题会对性能产生很大影响。本项目将采用 bottom-up 的设计思路，从更好地利用 CPU、磁盘等资源的角度出发，考虑如何自底向上解决 TiKV 的写热点问题。\n\n- 项目链接：https://gist.github.com/OneSizeFitsQuorum/da4b1e12b9f216fd3b42e88c57fd9e55\n\n![热点清零.png](https://img1.www.pingcap.com/prod/_855670a11b.png)\n\n\n**团队名称：Jiekun**\n\n- 项目名称：FSDS\n- 项目介绍：异构（Heterogeneous）存储在日常开发中非常常见，如用户在以 TiDB 作为 Primary Storage 时，也可能期望使用 Elasticsearch 作为搜索引擎、ClickHouse 作为 OLAP 存储。但 Secondary Storage 常常在 Primary Storage 使用了一段时间、业务有所增长的时候才被引入，因此数据同步就需要复制存量数据和同步增量数据。本项目将专注解决复制存量数据的问题，为 TiDB 提供全量数据导出的支持，方便构建异构存储/次级存储。\n- 项目链接：https://gist.github.com/jiekun/ac4387b613e91c2d4142df35614cab34\n\n**团队名称：我垫你们蹲**\n\n- 项目名称：TiFlash Collocated Optimization\n- 项目介绍：项目通过引入新的索引，来实现 TiDB 的协同优化能力，能够显著提升 TiDB 和 TiFlash 的性能，增强 TiDB 的分析处理能力，同时以非侵入性的方式保持其 HTAP 特性。\n- 项目链接：https://gist.github.com/zanmato1984/e9177d3f9b30023c16765d0161b4f43f\n\n![我垫你们蹲.png](https://img1.www.pingcap.com/prod/_d9964507fd.png)\n\n\n**团队名称：cdc-plg**\n\n- 项目名称：cdc sink plugin\n- 项目介绍：TiDB 官方开发了 TiCDC 项目以解决 TiDB 实时数据同步的问题。该项目旨在为 TiCDC 用户提供可扩展插件的方式，定制数据处理过程，提升 TiCDC 的扩展性。通过把 cdc 的 sink 以 plugin 的形式交付用户，让用户不需要重新编译 Tiflow 项目打包 TiCDC 就可以直接自定义逻辑，让用户可以把 TiKV 的数据从 TiCDC 发去全世界任何存储上。\n- 项目链接：https://github.com/mischaZhang/cdc-plg/blob/main/README.md\n\n![cdc-plg.png](https://img1.www.pingcap.com/prod/cdc_plg_d7d0280280.png)\n\n\n**团队名称：BetterTP**\n\n- 项目名称：BetterTP\n- 项目介绍：本项目旨在找出 RPC 往返可能对 TiDB 的 OLTP 性能的影响。在目前 TiDB 内核的架构和实现中，所有操作单元都是 RPC。找出 RPC 往返对 OLTP 性能的影响，可以进行针对性的优化，减少不必要的分布式执行，提高 TiDB 的 OLTP 性能。\n- 项目链接：https://github.com/TiDBHackers/rfc/blob/master/text/why_and_how_does_round_trip_matters.md\n\n![Better.png](https://img1.www.pingcap.com/prod/Better_fca5788762.png)\n\n## 超强评委阵容\n\n本届赛事邀请了数据库领域知名专家、社区技术大咖、顶级投资人代表等超强阵容担当评委，评委们将对项目进行全方位点评指导，深入挖掘项目闪光点，绝不放过每一个优秀项目！\n\n## 多维度奖项鼓励更多可能性  \n\n大赛总奖金池高达 35 万，除了一、二、三等排名奖项，还设置了 Cloud 应用生态奖、最佳校园奖、技术趋势奖等多个维度奖项，突破单一的评价体系。我们鼓励这个世界更多的可能性，让更多元的创意能够生根发芽。  \n\n10 月 22 日至 10 月 23 日，我们码上见！","author":"PingCAP","category":3,"customUrl":"list-of-finalists-in-tidb-hackathon-2022","fillInMethod":"writeDirectly","id":437,"summary":"TiDB Hackathon 2022 初赛结果出炉，哪些项目值得关注，快来看看吧！","tags":["TiDB Hackathon 2022"],"title":"TiDB Hackathon 2022 决赛入围名单出炉，哪些项目值得关注？快来围观吧！"}},{"relatedBlog":{"body":"目前，[TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 已经进入倒计时，距离决赛日还有不到一周时间，今年由于赛制的变化，初赛提前到了赛前（10 月 17 日），你已经准备好自己项目的 RFC 了吗？如果还没有，请注意 10 月 17 日是 RFC 收集最后截止日，如果还没有报名或准备 RFC 的小伙伴，要抓紧时间啦！\n\n为了帮助大家更从容地参加比赛，TiDB 社区本期访谈中采访了三位 Hackathon 参赛选手，他们有第一次参加的，也有参加 2 届的选手，希望通过访谈为大家分享一下他们的参赛经验。已经报名参加本届 Hackathon 的选手或是对 Hackathon 感兴趣的小伙们，值得一看！\n\n## 俞平\n\n第一位选手是来自 P 社内核组的俞平同学，他至今有两次 Hackathon 的经验，前年作为技术小组帮助选手解决问题，去年首次下场参赛。今年更是信心满满，决定向奖项发起冲击！\n\n以下为俞平同学的访谈记录：\n\n**Q 去年 TiDB Hackathon 中的参赛项目是什么**？\n\n**俞平**：去年我报名了生态组，是和两位社区的小伙们一起组队参加的。他们日常工作中就在用 TiDB 支持业务，遇到的最大问题是在用 TiCDC 做同步时，如果一个单表特别大的话，现有 TiCDC 的设计会有一些限制。所以，我们就把优化这个问题作为参赛题目，希望降低一些这个问题的限制。最后虽然离理想状态还有些距离，但也算有些效果，重在参与嘛。\n\n**Q 你是如何找到项目 idea 灵感的**？\n\n**俞平**：在 Hackathon 比赛中主要有两类 idea：一种是有趣好玩的，也是我比较喜欢的。将那种脑洞比较大，甚至有些不太正经的的想法带入项目中，比如去年用 minecraft 来展示 Chaos Mesh 运作方式的项目，前年用 VR 飞机驾驶舱的方式来展现 TiDB 运维的项目，我觉得这些 idea 真的非常棒；另一种就是像我们一样，在平时使用 TiDB 的过程中觉得有什么地方是可以优化提升的，那就可以将这个作为 idea 来参加比赛。\n\n**Q 在你眼中，这些年 TiDB Hackathon 有哪些变化**？\n\n**俞平**：我觉得 TiDB Hackathon 的内核其实一直没有改变过，借这个大赛大家可以有一个展示自己创意的机会。从比赛上来说，奖品越来越丰富，组织越来越完善了，去年设置了 4 个赛道，大家可以在不同赛道里比赛，能更好地找到自己的 idea。今年虽然改为 2 个赛道，但类别感觉更清晰了。产品赛道更偏向 TiDB 的内核，应用赛道更偏向业务场景，从 TiDB 的角度看，这两个方面都是紧密结合的领域。另外，今年我发现主办方从赛制上降低了了初赛的难度，大家可能终于可以不那么卷了。\n\n**Q 今年已经参赛了吗**？\n\n**俞平**：今年有一位大佬邀请我抱他的“大腿”，于是我和其他几位小伙伴就毫不犹豫地与大佬一起组队报名了。我们的队名叫“摸鱼就好”，项目应该属于产品组。\n\n**Q 开始写 RFC 了吗？有没有什么小技巧分享**？\n\n**俞平**：今年不让抢跑，所以还没有提交 RFC。写 RFC 有点类似于写设计文档，我的经验是主要由三个部分组成：首先要讲清楚我要做一个什么东西，这个东西长什么样子，它要解决什么问题，它的适用场景是什么，甚至可能它不解决什么样的问题。从这些方面把项目进行清晰的定义，这是比较重要的第一步；接下来就是介绍采取什么技术方案，曾经考虑过的备选方案是哪些，做了哪些权衡最终选择了当前技术方案；最后，还要加上做过哪些测试与验证。如果大家不知道怎么写，其实也可以查看一下往期的 RFC 是怎么写的，网上应该都可以查到。\n\nRFC 毕竟是文字的东西，在答辩里可以再加一些文字之外的东西，比如我这个 idea 产生的背景是什么，我们在过程中是怎么讨论的，有一个怎么样的心路历程，这样可以让评委更好理解，印象更深刻。\n\n**Q 今年有什么期待**？\n\n**俞平**：大佬说我们今年的项目冲击第一名还是有希望的，我尽力而为吧。\n\n## 夏力维\n\n下面这位选手是十年全栈工程师夏力维，前齐书在线即时文档工具早期工程师，多年创业，历经协同文档、O2O、美妆、工厂自动化运营脚本，堪称全能型选手。\n\n以下为夏力维同学的访谈记录：\n\n**Q 你都参加过哪些比赛类活动**？\n\n**夏力维**：自 2011 年参加“硅谷-上海黑客马拉松”后，我开始在技术社区活动较为积极参与。曾参与过由 AVOSCloud Hackathon 和 Autodesk 组织的 AEC Hackathon，并获得前三。在新技术体验和使用中，感受到了来自前沿科技公司对于新技术的普及与推广力度。在这个时代，没有那么商业与限制，更多是对于更好的技术与业务运用的结合，能看到平时看不到的技术应用和视野拓展。\n\n**Q TiDB Hackathon 有哪些方面吸引你**？\n\n**夏力维**：我很早就通过上海的 GDG 技术社区听说过 TiDB 的使命，我自己是 Bret Taylor 的忠实追随者，在数据结构部分有继承 FriendFeed 思想的 DB 方案产品，在面对 TiDB 时，期待有更好的结合。\n\n**Q 今年从什么渠道了解到 Hackathon？你选择哪个赛道**？\n\n**夏力维**：有一个友人推荐了项目，她老公是《剑指 Offer》的作者，也非常推荐 TiDB 的活动。我选择了应用组赛道，倒不是觉得这个赛道压力小，而是觉得这个赛道能够验证数据管理的过程中，其实是可以实现更高扩容性能的。今年也期待看到更多可以落地的应用产品，并且让很多人看到并能参与进来。\n\n**Q 队伍名字是什么？参赛项目是什么**？\n\n**夏力维**：我的队名叫 HOTPOOR，一个人的全栈工程师队伍。我的项目是像做 PPT 一样做网站建设，并且直接可用。而不是仅仅像 Figma 做设计，或者 Axure 做原型，对标产品 Gamma.app ，但要更自由。\n\n## 杜志刚\n\n最后这位选手是在软件开发行业拥有 20 年的工作经验的杜志刚。在中国 10 年，主要做编码工作；在日本 10 年，主要也是做编码工作，不同的是能吃到寿司和纳豆:P  。从 2018 年开始通过 Kubecon 了解到 TiDB，从此一发不可收拾，沉醉于 TiDB 的学习上。目前已经加入 P 社，从事日本本地的技术支持工作。\n\n**Q 去年你带来的是什么项目？能给其他选手分享一下提 idea 的经验或灵感吗**？\n\n**杜志刚**：去年我们带来了 [Ti-Click](/blog/ti-click) 的社区雏形，希望能让应用开发者用户更多地了解 TiDB，更好地使用 TiDB。PingCAP 目前在应用开发者方面做得还不够，包括 MySQL 生态圈的各种库和框架对 TiDB 的最佳适配还不够，比如 TiDB 可以更好地横向扩展，那么连接池也应该有所调整以便能用上新结点。课题很多，希望更多的应用开发者参加到 Hackathon 里来，从应用开发者角度出发，把 TiDB 玩得更好。\n\n**Q 在你眼中， 这些年来 TiDB Hackathon 有哪些变化**？\n\n**杜志刚**：今年的变化感觉比较大，从赛制上讲这次更加公平，不抢跑，限定 2 天编码，更接近极客精神；最吸引我的地方是可以感受到 TiDB 热情的社区氛围，观摩各路大神的精彩成果。\n\n同时，今年的赛道设置为 TiDB 产品组和应用组。我觉得应用组的增设非常好，因为我应用开发经验更多，更适合在这个领域施展。期待 TiDB“出圈” ，产品组固然很好很强大，但是局限于产品组来的人估计也都是老面孔了。应用组可以吸引更多的开发者来关注 TiDB，让 TiDB 的生态变得更强。\n\n**Q 目前是否已经组队？项目是什么方向**？\n\n杜志刚：我们的队伍还是叫 Ti 可立刻，打算继续从应用开发的角度或 DBA 的角度来寻找 idea，我们队的目标是面向 TiDB 的应用开发者服务。我们会根据主流编程语言推出一系列项目模版，内置应用程序使用 TiDB 的最佳实践，让应用程序最佳化使用 TiDB，少走弯路。同时我们还和 TiDB Cloud 一键集成，并且也针对应用开发者的本地开发需求和 CI 环境，提供 gitpod 和 docker-compose 方案，使得应用开发者省去配置这些周边环境的工作，集中精力实现自己的业务逻辑。\n\n**Q 作为老选手，你们 RFC 准备应该也比较有经验，有没有一些小技巧可以分享给今年的小伙伴们呢**？\n\n**杜志刚**：其实谈不上什么经验。不过我想它类似工作报告，只要表达清楚为什么做/要做什么/怎么做就好了。\n\n**Q 对自己的项目在比赛中有什么期待**？\n\n**杜志刚**：期待以此为契机，让 TiDB 的应用开发生态发展得更好。\n\n**Q 有没有一些其他参赛经验想分享给其他小伙伴的**？\n\n**杜志刚**：我仅参加过一年，经验不多。我自己想的是，好好享受社区的火热气氛，燃烧自己的热情，享受 Hackathon 的这个过程。\n\n通过三位选手的分享，想必也为大家提供了一些参赛经验和项目思路。总结一下，项目创意可以从平时遇到的问题出发，最好能做得好玩有趣一些。写 RFC 关键要写清楚项目的目标、解决哪些问题、适用场景、技术方案以及验证测试 DEMO。**关于如何设计 RFC，大家也可以看一下官方模板**：https://asktug.com/t/topic/903770\n\n最后，敲黑板说重点：**10 月 17 日是 RFC 收集最后截止日**，还没有报名或准备 RFC 的小伙伴要抓紧时间啦，赶上最后一班车~\n\n了解 [TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 更多详情，立即报名参加吧！","author":"PingCAP","category":3,"customUrl":"old-and-new-friends-in-tidb-hackathon","fillInMethod":"writeDirectly","id":431,"summary":"TiDB Hackathon 2022 已经进入倒计时，距离决赛日还有不到一周时间，今年由于赛制的变化，初赛提前到了赛前（10 月 17 日），你已经准备好自己项目的 RFC 了吗？","tags":["TiDB Hackathon 2022"],"title":"老朋友新朋友，抱紧“大腿”，冲击第一名！ | TiDB Hackathon 选手访谈"}}]},{"id":"Blogs_437","title":"TiDB Hackathon 2022 决赛入围名单出炉，哪些项目值得关注？快来围观吧！","tags":["TiDB Hackathon 2022"],"category":{"name":"社区动态"},"summary":"TiDB Hackathon 2022 初赛结果出炉，哪些项目值得关注，快来看看吧！","body":"自 2022 年 9 月 13 日开放报名以来，TiDB Hackathon 2022 共吸引了 303 人报名参赛，由此诞生了 86 支队伍，评委组从应用性/实用性、创新性、完成度、展示度四个维度对大家提交的 RFC 严格筛选，有 62 支队伍成功入围决赛：\n\n![应用组入围.jpeg](https://img1.www.pingcap.com/prod/_c69487e38f.jpeg)\n\n![产品组入围.jpeg](https://img1.www.pingcap.com/prod/_0bf299375b.jpeg)\n\n恭喜以上队伍晋级决赛！\n\n**温馨提示**：决赛入围名单公示之后（即刻起），大家就可以开始准备代码开发。决赛现场评委会严格审查参赛选手的作品是否符合“第一行代码提交时间需在初赛结果公示后”这一规则。\n\n决赛将于 10 月 22 日至 10 月 23 日在上海、北京、广州、成都、新加坡等地的 PingCAP 公司举行，请入围选手 10 月 22 日上午 9:00-10:00 到达决赛现场，签到并领取参赛礼品，决赛详细流程参见[参赛须知](https://asktug.com/t/topic/994153)。其他提交 RFC 的赛队也将获得本次活动的电子参赛证书（将发放给到队长），也欢迎大家线上围观决赛，并参与最佳人气项目的投票，参与投票的小伙伴还有机会抽取礼品哟！\n\n![参赛证书.png](https://img1.www.pingcap.com/prod/_95121197ef.png)\n<center>参赛证书</center>\n\n10 月 22 日上午 10:00 至 10 月 23 日中午 12:00 选手们将在决赛现场 hack，10 月 23 日 13:00 正式开始现场答辩。\n\n届时，小伙伴也能线上围观这场技术盛宴。两个赛道分别在不同平台同时直播，PingCAP 微信视频号将直播 TiDB 产品组的答辩赛况、B 站 TiDB_Robot 账号将直播应用组的答辩赛况，大家可以合理安排时间，优先选择自己更感兴趣的赛道观看直播哟！\n\n## 最佳人气奖\n\n最佳人气奖投票通道已经开启，欢迎 pick 你中意的团队！票数最高的团队将获得最佳人气奖。\n\n投票用户也可参与抽奖，将在投票用户中抽取 5 位，每人送出“TiDB 社区限定挎包”一只。\n\n![限定挎包.jpeg](https://img1.www.pingcap.com/prod/_58590dbb76.jpeg)\n\n投票时间：即时起 - 10 月 23 日答辩结束\n\n投票规则：应用组与 TiBD 产品组 分别投票，每人每个赛道一票\n\n投票方式：扫码即可参与投票\n\n![参与投票.png](https://img1.www.pingcap.com/prod/_3bfdb338a5.png)\n\n## 现场精彩看点\n\n### 项目值得期待\n\n本届参赛项目再一次打开了我们对于 TiDB 想象力的界限。极客们丰富的想象力，会让你大开眼界，重拾对技术探索的激情。先剧透几个有趣的项目给大家～\n\n#### 应用组\n\n**团队名称：Ti 可立刻**\n\n- 项目名称：Ti-Click++\n- 项目介绍：通过 Online IDE 的方式，可以让用户以最简便的方式部署 Sample App。在去年的 TiDB Hackathon 中，这个项目就收获了评委和观众的一致赞赏，并最终晋级 20 强。今年的改进版 Ti-Click++ 将使用 gitpod 的云服务，一次性解决 Eclipse Che 运维难和资源消耗问题。此外将统一业务模型，使用 Real World 的模板进行改造，让用户只需要理解一种业务，但是可以同时理解多种语言链接和使用 TiDB 的方案。\n- 项目链接：https://github.com/ti-click/pingcap-hackathon-2022\n\n**团队名称：cloud naive**\n\n- 项目名称：My Life\n- 项目介绍：My Life 项目希望能记录我们的生活轨迹，存储到 TiDB 中，最终以各种方式展现。项目将基于低代码技术去实现，通过 TiDB Cloud 集成低代码产品 zapier/n8n。\n- 项目链接：https://gist.github.com/shiyuhang0/ae6d9deab4c8e1708b80bea1de9df279\n\n![cloud native.png](https://img1.www.pingcap.com/prod/cloud_native_ff91c09191.png)\n\n**团队名称：不上班你养我啊**\n\n- 项目名称：云迹\n- 项目介绍：成本优化不仅对于公司有着重要意义，也是每个云上开发人员都需要具备的 sense。本项目终极目的是解决企业在云上部署架构下统一成本分析、关键指标监控告警的问题。因考虑到数据量巨大，统计分析实时查询、告警要求多，我们采用 HTAP 数据库的 TiDB 作为存储和计算引擎，发挥 TiDB 在应用场景下的价值。期待可以通过云迹，节约你的金钱亿点点！\n- 项目链接：https://gist.github.com/VelocityLight/ccb4c50e569b1ee733f23a2bb97e8439\n\n![不上班.png](https://img1.www.pingcap.com/prod/_a048f90102.png)\n\n**团队名称：KubeBrain**\n\n- 项目名称：KubeBrain\n- 项目介绍：当前 Kubernetes 仅支持 etcd 作为元信息存储系统，因此部署 Kubernetes 集群总是需要额外的维护一套 etcd 集群，etcd 集群并不支持水平扩容，随着数据量和读写请求量的增长，容易达到瓶颈。我们实现了轻量级 Kubernetes 元信息存储项目 KubeBrain 对存储引擎 API 进行抽象，希望可以通过适配不同的分布式存储系统，从而可以充分利用已有的存储系统作为基础设施来部署 Kubernetes 集群，支持一定程度的元信息存储的水平扩容，打通 Kubernetes 和其他存储系统之间的壁垒。\n- 项目链接：https://gist.github.com/divanodestiny/fd4f957cdc3a099414e7a93459168958\n\n![KubeBrain.png](https://img1.www.pingcap.com/prod/Kube_Brain_4e3cea8e08.png)\n\n**团队名称：1' or '1' = '1**\n\n- 项目名称：TiSQLi\n- 项目介绍：通过 pincap/tidb/parser 对 SQL 对解析能力，对于 Web 接口潜在的 SQL 注入进行检测、拦截和防范。可进一步扩展用于：片段 SQL 语句的注入检测，如 WAF 等网关设备，或者应用内的前置过滤器；完整 SQL 语句的注入检测，如数据库内置的 SQL 检测，或者应用内的数据库中间件。\n- 项目链接：https://gist.github.com/flily/c1009c65e08eaed28e9f39f1d371cea7\n\n#### TiDB 产品组\n\n**团队名称：热点清零**\n\n- 项目名称：Fearless Write Hotspot\n\n- 项目介绍：在分布式系统中，部分热点节点会承载大量用户的读写请求，而单个机器的负载往往是有限的；在单节点上，部分热点线程会承载大量的计算任务，而单核的性能往往也是有限的。整体来看，热点问题会对性能产生很大影响。本项目将采用 bottom-up 的设计思路，从更好地利用 CPU、磁盘等资源的角度出发，考虑如何自底向上解决 TiKV 的写热点问题。\n\n- 项目链接：https://gist.github.com/OneSizeFitsQuorum/da4b1e12b9f216fd3b42e88c57fd9e55\n\n![热点清零.png](https://img1.www.pingcap.com/prod/_855670a11b.png)\n\n\n**团队名称：Jiekun**\n\n- 项目名称：FSDS\n- 项目介绍：异构（Heterogeneous）存储在日常开发中非常常见，如用户在以 TiDB 作为 Primary Storage 时，也可能期望使用 Elasticsearch 作为搜索引擎、ClickHouse 作为 OLAP 存储。但 Secondary Storage 常常在 Primary Storage 使用了一段时间、业务有所增长的时候才被引入，因此数据同步就需要复制存量数据和同步增量数据。本项目将专注解决复制存量数据的问题，为 TiDB 提供全量数据导出的支持，方便构建异构存储/次级存储。\n- 项目链接：https://gist.github.com/jiekun/ac4387b613e91c2d4142df35614cab34\n\n**团队名称：我垫你们蹲**\n\n- 项目名称：TiFlash Collocated Optimization\n- 项目介绍：项目通过引入新的索引，来实现 TiDB 的协同优化能力，能够显著提升 TiDB 和 TiFlash 的性能，增强 TiDB 的分析处理能力，同时以非侵入性的方式保持其 HTAP 特性。\n- 项目链接：https://gist.github.com/zanmato1984/e9177d3f9b30023c16765d0161b4f43f\n\n![我垫你们蹲.png](https://img1.www.pingcap.com/prod/_d9964507fd.png)\n\n\n**团队名称：cdc-plg**\n\n- 项目名称：cdc sink plugin\n- 项目介绍：TiDB 官方开发了 TiCDC 项目以解决 TiDB 实时数据同步的问题。该项目旨在为 TiCDC 用户提供可扩展插件的方式，定制数据处理过程，提升 TiCDC 的扩展性。通过把 cdc 的 sink 以 plugin 的形式交付用户，让用户不需要重新编译 Tiflow 项目打包 TiCDC 就可以直接自定义逻辑，让用户可以把 TiKV 的数据从 TiCDC 发去全世界任何存储上。\n- 项目链接：https://github.com/mischaZhang/cdc-plg/blob/main/README.md\n\n![cdc-plg.png](https://img1.www.pingcap.com/prod/cdc_plg_d7d0280280.png)\n\n\n**团队名称：BetterTP**\n\n- 项目名称：BetterTP\n- 项目介绍：本项目旨在找出 RPC 往返可能对 TiDB 的 OLTP 性能的影响。在目前 TiDB 内核的架构和实现中，所有操作单元都是 RPC。找出 RPC 往返对 OLTP 性能的影响，可以进行针对性的优化，减少不必要的分布式执行，提高 TiDB 的 OLTP 性能。\n- 项目链接：https://github.com/TiDBHackers/rfc/blob/master/text/why_and_how_does_round_trip_matters.md\n\n![Better.png](https://img1.www.pingcap.com/prod/Better_fca5788762.png)\n\n## 超强评委阵容\n\n本届赛事邀请了数据库领域知名专家、社区技术大咖、顶级投资人代表等超强阵容担当评委，评委们将对项目进行全方位点评指导，深入挖掘项目闪光点，绝不放过每一个优秀项目！\n\n## 多维度奖项鼓励更多可能性  \n\n大赛总奖金池高达 35 万，除了一、二、三等排名奖项，还设置了 Cloud 应用生态奖、最佳校园奖、技术趋势奖等多个维度奖项，突破单一的评价体系。我们鼓励这个世界更多的可能性，让更多元的创意能够生根发芽。  \n\n10 月 22 日至 10 月 23 日，我们码上见！","date":"2022-10-19","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"list-of-finalists-in-tidb-hackathon-2022","file":null,"relatedBlogs":[{"relatedBlog":{"body":"![hackathon 2022 kv.jpeg](https://img1.www.pingcap.com/prod/hackathon_2022_kv_000f450a54.jpeg)\n\n一年一度的 TiDB Hackathon 又来啦！\n\n[TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 主题为「**Possibility at Scale**」，9 月 13 日正式开启，线下决赛将在 2022 年 10 月 22 - 23 日举行。期待与你一起打破传统技术边界，突破固有思维局限，用 TiDB 释放创新的更多可能性。\n\n本届 TiDB Hackathon 将面向更广泛人群，分为**应用组**与 **TiDB 产品组**两大赛道。无论你是应用开发者、数据库开发者、数据库上下游生态从业人员，还是数据库使用者，都可以找到适合自己的方向，一起“玩转” TiDB。\n\nTiDB Hackathon 报名通道于 2022 年 9 月 13 日正式开启，**选手们可以自行组队参赛，通过初赛甄选后，将在现场完成 Coding 及决赛答辩，优胜队伍将获得奖金、技术和资源商的支持**。大赛评委阵容豪华，数据库领域资深专家、社区技术大牛、顶级投资人代表将对项目进行深度点评。此外，还有顶级投资人全程参与评选，让你的实力被更多人看到。\n\n**扫描下图二维码，立即报名参赛**，或前往 [TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 活动页报名。\n\n![报名参赛.jpeg](https://img1.www.pingcap.com/prod/_f7bfacf978.jpeg)\n\n从 2017 年到 2022 年，TiDB Hackathon 不断升级，吸引了全球 1000 + 技术爱好者参与，先后诞生了诸如 UDF 引擎、TiExec、TiMatch 等深受好评的硬核项目，也有 zh.md、TiDB 驾驶舱、pCloud 等新颖有趣的项目。同时，部分优秀项目还在海内外媒体平台获得了多重曝光，借助 TiDB 社区力量为项目提供更多生命力。\n\n在 TiDB Hackathon ，你可以尽情发挥想象力与创造力，全情投入，实现自己的 idea。我们希望你可以永葆对技术的热情与好奇心，在代码的世界中勇敢探索、一往无前。我们在 TiDB Hackathon 2022 等你，期待与你共赴这场技术盛宴！\n\n## 赛事亮点\n\n🌟 **奖金丰厚**\n\n大赛总奖金池高达 35 万元，奖项多达 10+ 个，涵盖各个方向，力求全方位挖掘各参赛项目的价值。\n\n🌟 **各路大神同台竞技**\n\n技术大神齐聚一堂，上演“神仙打架”，场面超燃。高手之间的巅峰对决，精彩纷呈，让人大开眼界。\n\n🌟 **高质量交流**\n\n数据领域知名专家、社区技术大牛担任大赛评委，对项目进行深入点评，还有顶级投资人全程参与评选，你将不止收获硬核的技术反馈，还会获得前瞻性启发。\n\n🌟 **优秀项目专题采访**\n\n大赛结束后，我们将对优秀项目进行专题采访，在海内外技术圈多重曝光，提升优秀项目的知名度，借助 TiDB 社区力量为项目提供更多生命力。\n\n## 丰厚奖金\n\n**奖金池 35 万元，10+ 奖项，20+ 获奖团队**\n\n![丰厚奖金.jpeg](https://img1.www.pingcap.com/prod/_d265519d19.jpeg)\n\n**神秘定制社区周边**\n\n![定制社区周边.jpeg](https://img1.www.pingcap.com/prod/_c6c05c4a61.jpeg)\n\n## 参赛对象\n\n不管你是数据库内核工程师、数据库生态上下游开发者，还是应用开发者，只要你有 idea，都可以报名参赛，一展你的风采！\n\n## 赛道设置\n\n**应用组**\n\n以体现 TiDB 产品价值为主，基于 TiDB 之上实现代码开源的产品、工具、应用等均可。部署方式上，更推荐基于 Cloud 构建 TiDB 相关应用。推荐领域：游戏、电商、金融科技、公益等。\n\n**TiDB 产品组**\n\n为 TiDB 内核产品以及 TiCDC、TiDB Lightning、TiUP 等周边工具的性能、稳定性、易用性或功能等各方面做出提升。\n\n## 赛程安排\n\n- 报名：即日起 - 10 月 17 日，开启报名\n\n- 组队：9 月 17 日，参加「非正式会谈 — 创意脑暴会」，获取项目灵感（详见下方介绍）\n\n- 线上初赛：报名后 -  10 月 17 日，提交 RFC 进入初赛环节\n\n- 名单公布：10 月 19 日，查看决赛入围名单\n\n- 现场 Coding & 决赛：10 月 22 日 - 10 月 23 日，现场 Coding & 决赛答辩\n\n![比赛日程.png](https://img1.www.pingcap.com/prod/_357da0cc3c.png)\n\n## 评委阵容\n\n数据库领域知名专家、社区技术大牛、顶级投资人代表等担当评委，还有顶级投资人全程坐镇，对比赛项目深入点评。\n\n![评委.png](https://img1.www.pingcap.com/prod/_db0a886a7b.png)\n\n<center>（评委按姓名首字母排序）</center>\n\n比赛有输赢，技术无高低。即便最终未能问鼎巅峰，朝着心之所向全力冲刺依旧是一段值得回忆的旅程。秉承不断突破和创造的黑客精神，来一场技术的狂欢盛宴吧。放码过来！\n\n## 创意脑暴会给你灵感\n\n**TiDB Hackathon 2022 非正式会谈 —— 创意脑暴会**来啦，这里有超多 idea，特邀东旭以及资深架构师们在线脑暴，给你超丰富项目灵感。9月17日 本周六 10:30-12:00（GTM+8），线上见～\n\n![创意脑暴.jpeg](https://img1.www.pingcap.com/prod/_a800efa48b.jpeg)\n\n## 合作伙伴\n\n![合作伙伴.png](https://img1.www.pingcap.com/prod/_c6b365d0d3.png)\n\n了解 [TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 更多精彩！\n\n","author":"PingCAP","category":3,"customUrl":"tidb-hackathon-2022-is-coming","fillInMethod":"writeDirectly","id":426,"summary":"一年一度的 TiDB Hackathon 又来啦！TiDB Hackathon 2022 主题为「Possibility at Scale」,9 月 13 日正式开启，线下决赛将在 2022 年 10 月 22 日 23 日举行。","tags":["TiDB Hackathon 2022"],"title":"TiDB Hackathon 2022丨总奖金池超 35 万！邀你唤醒代码世界的更多可能性！"}},{"relatedBlog":{"body":"![banner.jpeg](https://img1.www.pingcap.com/prod/banner_6e96e050b4.jpeg)\n\n一年一度黑客们的狂欢——[TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 报名已开启，万元奖金等你来拿，还有技术专家、顶级投资人全程坐镇，你的实力将被更多人看到。\n\nTiBD Hackathon 2022 ·「Possibility at Scale」，邀请你一起打破传统技术边界，突破固有思维局限，用 TiDB 释放创新的更多可能性。\n\n悄悄说：今年真的不卷，值得一试！\n\n两大赛道，任选：\n\n- 应用组：推荐噢，因为特别奖项更多！\n\n以体现 TiDB 产品价值为主，使用 TiDB 构建代码开源的产品、工具、应用等均可。部署方式上，更推荐基于 Cloud 构建 TiDB 相关应用。常见应用领域：游戏、电商、金融科技、公益等。\n\n- TiDB 产品组：延续传统，保持初心\n\n为 TiDB 内核产品以及 TiCDC、TiDB Lightning、TiUP 等周边工具的性能、稳定性、易用性或功能等各方面做出提升。\n\n扫描下方二维码立即报名参与！\n\n![报名.jpeg](https://img1.www.pingcap.com/prod/_3b43724e2f.jpeg)\n\n听说你想参加 TiDB Hackathon，却没有 idea？\n\n别担心，脑洞达人东旭和他的架构师朋友们在创意脑暴会上分享的项目 idea 都整理好啦，快来看看有没有你感兴趣的~（ps：搭配视频查看 idea 详细介绍，效果更佳哦~） \n\n**创意贡献嘉宾**\n\n黄东旭 PingCAP 联合创始人兼 CTO\n\n姚维 PingCAP 全球社区生态负责人\n\n张兴晔 多点系统架构师\n\nCheng Chen PingCAP Product Manager\n\n[脑暴会视频](https://www.bilibili.com/video/BV1yG411u7N9/)\n\n## 应用组\n\n![应用组.jpeg](https://img1.www.pingcap.com/prod/_e769b14808.jpeg)\n\n今年应用组的决赛参赛项目仅要求是 demo 级别的，例如以下项目示例：\n\n- OSS Insight：https://ossinsight.io/\n\n这是一个基于 TiDB 实现的，数十亿 GitHub events 数据构建的洞察工具。只要你会写 SQL，就可以基于 Docusaurus、Apache ECharts 构建一个强大、酷炫的数据洞察工具。\n\n- TiDB & Snowflake Demo：https://tidb-snowflake-e-commerce-demo.vercel.app/\n\n这是一个基于 TiDB 和 Snowflake 构建的电子商务系统，该系统使用了 TiDB 强大的实时 HTAP 能力和 Snowflake 的离线分析能力，来处理系统中大量的数据。\n\n- Ti-Click：http://ide.ti-click.com/\n\n这是 TiDB Hackathon 2021 的 20 强项目之一，项目通过在线 IDE 的方式，快速搭建基于 TiDB 的 Example App 的开发和在线编译的实验室，可帮助开发者快速学习 TiDB。\n\n- Bookshop\n\n这是一个基于 TiDB 搭建的在线书店应用，你可以通过它来学习如何导入表结构和数据，以及如何基于这些数据来编写 SQL。\n\n[这篇文章](https://docs.pingcap.com/zh/tidb/stable/dev-guide-bookshop-schema-design)也以 Bookshop 应用的数据表结构和数据为基础来编写示例 SQL，为你介绍如何导入该应用的表结构和数据，以及其数据表结构的定义。\n\n- Gitpod\n\n对于 TiDB 初学者，我们基于 Gitpod，提供了一个云原生开发环境的使用帮助，你可以直接从你的浏览器或桌面 IDE 启动一个远程的 TiDB 开发环境，快速体验 TiDB 的能力。我们编写了全新的 TiDB 开发者文档，这份文档可以帮助应用开发者，在最短时间内上手 TiDB。\n\nTiDB 开发者文档：https://docs.pingcap.com/zh/tidb/stable/dev-guide-overview\n\n## TiDB 产品组\n\n![TiDB 产品组.jpeg](https://img1.www.pingcap.com/prod/Ti_DB_77ad779a1c.jpeg)\n\n## 彩蛋组\n\n彩蛋组不可更改 TiDB/TiKV 源码，仅可使用插件方式进行 Hack。\n\n![彩蛋组.jpeg](https://img1.www.pingcap.com/prod/_f6b386df89.jpeg)\n\n希望可以给你一些方向与灵感！更多项目 idea 也可以来 [Hackathon 2022 创意库](https://asktug.com/t/topic/933124)找灵感。\n\n看到这么多 idea，你是否跃跃欲试了呢？\n\n热爱编程，勇于探索，就能参赛\n\n你离万元大奖只有一个报名的距离~\n\n了解 [TiDB Hackathon 2022 ](https://tidb.net/events/hackathon2022)更多详情！","author":"PingCAP","category":3,"customUrl":"hackathon-idea-list-for-reference","fillInMethod":"writeDirectly","id":427,"summary":"一年一度黑客们的狂欢——TiDB Hackathon 2022 报名已开启，万元奖金等你来拿，还有技术专家、顶级投资人全程坐镇，你的实力将被更多人看到。","tags":["TiDB Hackathon 2022"],"title":"Hackathon idea 清单出炉，总有一款适合你"}},{"relatedBlog":{"body":"目前，[TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 已经进入倒计时，距离决赛日还有不到一周时间，今年由于赛制的变化，初赛提前到了赛前（10 月 17 日），你已经准备好自己项目的 RFC 了吗？如果还没有，请注意 10 月 17 日是 RFC 收集最后截止日，如果还没有报名或准备 RFC 的小伙伴，要抓紧时间啦！\n\n为了帮助大家更从容地参加比赛，TiDB 社区本期访谈中采访了三位 Hackathon 参赛选手，他们有第一次参加的，也有参加 2 届的选手，希望通过访谈为大家分享一下他们的参赛经验。已经报名参加本届 Hackathon 的选手或是对 Hackathon 感兴趣的小伙们，值得一看！\n\n## 俞平\n\n第一位选手是来自 P 社内核组的俞平同学，他至今有两次 Hackathon 的经验，前年作为技术小组帮助选手解决问题，去年首次下场参赛。今年更是信心满满，决定向奖项发起冲击！\n\n以下为俞平同学的访谈记录：\n\n**Q 去年 TiDB Hackathon 中的参赛项目是什么**？\n\n**俞平**：去年我报名了生态组，是和两位社区的小伙们一起组队参加的。他们日常工作中就在用 TiDB 支持业务，遇到的最大问题是在用 TiCDC 做同步时，如果一个单表特别大的话，现有 TiCDC 的设计会有一些限制。所以，我们就把优化这个问题作为参赛题目，希望降低一些这个问题的限制。最后虽然离理想状态还有些距离，但也算有些效果，重在参与嘛。\n\n**Q 你是如何找到项目 idea 灵感的**？\n\n**俞平**：在 Hackathon 比赛中主要有两类 idea：一种是有趣好玩的，也是我比较喜欢的。将那种脑洞比较大，甚至有些不太正经的的想法带入项目中，比如去年用 minecraft 来展示 Chaos Mesh 运作方式的项目，前年用 VR 飞机驾驶舱的方式来展现 TiDB 运维的项目，我觉得这些 idea 真的非常棒；另一种就是像我们一样，在平时使用 TiDB 的过程中觉得有什么地方是可以优化提升的，那就可以将这个作为 idea 来参加比赛。\n\n**Q 在你眼中，这些年 TiDB Hackathon 有哪些变化**？\n\n**俞平**：我觉得 TiDB Hackathon 的内核其实一直没有改变过，借这个大赛大家可以有一个展示自己创意的机会。从比赛上来说，奖品越来越丰富，组织越来越完善了，去年设置了 4 个赛道，大家可以在不同赛道里比赛，能更好地找到自己的 idea。今年虽然改为 2 个赛道，但类别感觉更清晰了。产品赛道更偏向 TiDB 的内核，应用赛道更偏向业务场景，从 TiDB 的角度看，这两个方面都是紧密结合的领域。另外，今年我发现主办方从赛制上降低了了初赛的难度，大家可能终于可以不那么卷了。\n\n**Q 今年已经参赛了吗**？\n\n**俞平**：今年有一位大佬邀请我抱他的“大腿”，于是我和其他几位小伙伴就毫不犹豫地与大佬一起组队报名了。我们的队名叫“摸鱼就好”，项目应该属于产品组。\n\n**Q 开始写 RFC 了吗？有没有什么小技巧分享**？\n\n**俞平**：今年不让抢跑，所以还没有提交 RFC。写 RFC 有点类似于写设计文档，我的经验是主要由三个部分组成：首先要讲清楚我要做一个什么东西，这个东西长什么样子，它要解决什么问题，它的适用场景是什么，甚至可能它不解决什么样的问题。从这些方面把项目进行清晰的定义，这是比较重要的第一步；接下来就是介绍采取什么技术方案，曾经考虑过的备选方案是哪些，做了哪些权衡最终选择了当前技术方案；最后，还要加上做过哪些测试与验证。如果大家不知道怎么写，其实也可以查看一下往期的 RFC 是怎么写的，网上应该都可以查到。\n\nRFC 毕竟是文字的东西，在答辩里可以再加一些文字之外的东西，比如我这个 idea 产生的背景是什么，我们在过程中是怎么讨论的，有一个怎么样的心路历程，这样可以让评委更好理解，印象更深刻。\n\n**Q 今年有什么期待**？\n\n**俞平**：大佬说我们今年的项目冲击第一名还是有希望的，我尽力而为吧。\n\n## 夏力维\n\n下面这位选手是十年全栈工程师夏力维，前齐书在线即时文档工具早期工程师，多年创业，历经协同文档、O2O、美妆、工厂自动化运营脚本，堪称全能型选手。\n\n以下为夏力维同学的访谈记录：\n\n**Q 你都参加过哪些比赛类活动**？\n\n**夏力维**：自 2011 年参加“硅谷-上海黑客马拉松”后，我开始在技术社区活动较为积极参与。曾参与过由 AVOSCloud Hackathon 和 Autodesk 组织的 AEC Hackathon，并获得前三。在新技术体验和使用中，感受到了来自前沿科技公司对于新技术的普及与推广力度。在这个时代，没有那么商业与限制，更多是对于更好的技术与业务运用的结合，能看到平时看不到的技术应用和视野拓展。\n\n**Q TiDB Hackathon 有哪些方面吸引你**？\n\n**夏力维**：我很早就通过上海的 GDG 技术社区听说过 TiDB 的使命，我自己是 Bret Taylor 的忠实追随者，在数据结构部分有继承 FriendFeed 思想的 DB 方案产品，在面对 TiDB 时，期待有更好的结合。\n\n**Q 今年从什么渠道了解到 Hackathon？你选择哪个赛道**？\n\n**夏力维**：有一个友人推荐了项目，她老公是《剑指 Offer》的作者，也非常推荐 TiDB 的活动。我选择了应用组赛道，倒不是觉得这个赛道压力小，而是觉得这个赛道能够验证数据管理的过程中，其实是可以实现更高扩容性能的。今年也期待看到更多可以落地的应用产品，并且让很多人看到并能参与进来。\n\n**Q 队伍名字是什么？参赛项目是什么**？\n\n**夏力维**：我的队名叫 HOTPOOR，一个人的全栈工程师队伍。我的项目是像做 PPT 一样做网站建设，并且直接可用。而不是仅仅像 Figma 做设计，或者 Axure 做原型，对标产品 Gamma.app ，但要更自由。\n\n## 杜志刚\n\n最后这位选手是在软件开发行业拥有 20 年的工作经验的杜志刚。在中国 10 年，主要做编码工作；在日本 10 年，主要也是做编码工作，不同的是能吃到寿司和纳豆:P  。从 2018 年开始通过 Kubecon 了解到 TiDB，从此一发不可收拾，沉醉于 TiDB 的学习上。目前已经加入 P 社，从事日本本地的技术支持工作。\n\n**Q 去年你带来的是什么项目？能给其他选手分享一下提 idea 的经验或灵感吗**？\n\n**杜志刚**：去年我们带来了 [Ti-Click](/blog/ti-click) 的社区雏形，希望能让应用开发者用户更多地了解 TiDB，更好地使用 TiDB。PingCAP 目前在应用开发者方面做得还不够，包括 MySQL 生态圈的各种库和框架对 TiDB 的最佳适配还不够，比如 TiDB 可以更好地横向扩展，那么连接池也应该有所调整以便能用上新结点。课题很多，希望更多的应用开发者参加到 Hackathon 里来，从应用开发者角度出发，把 TiDB 玩得更好。\n\n**Q 在你眼中， 这些年来 TiDB Hackathon 有哪些变化**？\n\n**杜志刚**：今年的变化感觉比较大，从赛制上讲这次更加公平，不抢跑，限定 2 天编码，更接近极客精神；最吸引我的地方是可以感受到 TiDB 热情的社区氛围，观摩各路大神的精彩成果。\n\n同时，今年的赛道设置为 TiDB 产品组和应用组。我觉得应用组的增设非常好，因为我应用开发经验更多，更适合在这个领域施展。期待 TiDB“出圈” ，产品组固然很好很强大，但是局限于产品组来的人估计也都是老面孔了。应用组可以吸引更多的开发者来关注 TiDB，让 TiDB 的生态变得更强。\n\n**Q 目前是否已经组队？项目是什么方向**？\n\n杜志刚：我们的队伍还是叫 Ti 可立刻，打算继续从应用开发的角度或 DBA 的角度来寻找 idea，我们队的目标是面向 TiDB 的应用开发者服务。我们会根据主流编程语言推出一系列项目模版，内置应用程序使用 TiDB 的最佳实践，让应用程序最佳化使用 TiDB，少走弯路。同时我们还和 TiDB Cloud 一键集成，并且也针对应用开发者的本地开发需求和 CI 环境，提供 gitpod 和 docker-compose 方案，使得应用开发者省去配置这些周边环境的工作，集中精力实现自己的业务逻辑。\n\n**Q 作为老选手，你们 RFC 准备应该也比较有经验，有没有一些小技巧可以分享给今年的小伙伴们呢**？\n\n**杜志刚**：其实谈不上什么经验。不过我想它类似工作报告，只要表达清楚为什么做/要做什么/怎么做就好了。\n\n**Q 对自己的项目在比赛中有什么期待**？\n\n**杜志刚**：期待以此为契机，让 TiDB 的应用开发生态发展得更好。\n\n**Q 有没有一些其他参赛经验想分享给其他小伙伴的**？\n\n**杜志刚**：我仅参加过一年，经验不多。我自己想的是，好好享受社区的火热气氛，燃烧自己的热情，享受 Hackathon 的这个过程。\n\n通过三位选手的分享，想必也为大家提供了一些参赛经验和项目思路。总结一下，项目创意可以从平时遇到的问题出发，最好能做得好玩有趣一些。写 RFC 关键要写清楚项目的目标、解决哪些问题、适用场景、技术方案以及验证测试 DEMO。**关于如何设计 RFC，大家也可以看一下官方模板**：https://asktug.com/t/topic/903770\n\n最后，敲黑板说重点：**10 月 17 日是 RFC 收集最后截止日**，还没有报名或准备 RFC 的小伙伴要抓紧时间啦，赶上最后一班车~\n\n了解 [TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 更多详情，立即报名参加吧！","author":"PingCAP","category":3,"customUrl":"old-and-new-friends-in-tidb-hackathon","fillInMethod":"writeDirectly","id":431,"summary":"TiDB Hackathon 2022 已经进入倒计时，距离决赛日还有不到一周时间，今年由于赛制的变化，初赛提前到了赛前（10 月 17 日），你已经准备好自己项目的 RFC 了吗？","tags":["TiDB Hackathon 2022"],"title":"老朋友新朋友，抱紧“大腿”，冲击第一名！ | TiDB Hackathon 选手访谈"}},{"relatedBlog":{"body":"![Possibility at scale.jpeg](https://img1.www.pingcap.com/prod/Possibility_at_scale_9f90da9a4e.jpeg)\n\nTiDB Hackathon 2022 决赛刚好在 1024 程序员节前夜完美收官，48 小时的 Happy Hacking，参赛项目有趣、有料，精彩不断！  \n\n本届大赛主题为「Possibility at Scale」，规模创历史之最，共有 303 名选手报名 ，86 支队伍参赛，有来自微软、蚂蚁集团、字节跳动、网易有道、浪潮、明朝万达、B 站、思科、太极图形等企业的选手，也有来自清华大学、北京邮电大学、华东师范大学、浙江理工大学、新加坡国立大学等高校的学生。选手们围绕着 TiDB 产品组和应用组两大赛道，展开了一场技术的比拼和创意的碰撞。  \n\nHackathon，即“黑客马拉松”，是程序员非常喜闻乐见的赛事活动。它有着自由的形式：Hacker 们聚集在一起，紧密合作，发挥创意，持续编程，实现创想。编程马拉松的精髓在于：一群志同道合的伙伴，在特定的时间内，相聚在一起，去做他们想做的事情——整个编程的过程几乎没有任何限制。  \n\n作为一个已经举办了 5 年的赛事，PingCAP 联合创始人兼 CTO 黄东旭总是焦虑上届已经办得非常成功，这届达不到上届水准怎么办？但当看到选手们的精彩展示后，我们发现随着开发者们对 TiDB 的理解和使用越来越纯熟，Hackathon 的质量也在不断进化。最终，在两天一夜的 Hacking Time 中，有 16 支队伍瓜分了总计 35 万元的奖金，其中有 10 支队伍分获最佳创意奖、公益贡献奖、技术趋势奖、Cloud 应用生态奖、最佳人气奖、最佳校园奖、用户之选奖。\n\n## 硕果累累，项目创意无限\n\n评委老师们认为本届参赛队的很多项目“很有野心”，并已经具备落地的成熟度。例如「图一乐」队通过 “Data Dance” 提供了一个允许你探索、分析、理解数据的在线服务；「12 只喵」队伍让所有人都能通过 TiUP 个人镜像向 TiDB 贡献组件，打造组件市场的雏形；「我垫你们蹲」队通过引入新的索引来实现 TiDB 的协同优化能力的“TiFlash Collocated Optimization”；「cdc-plg」队为 TiCDC 用户提供可扩展插件的“cdc sink plugin”项目；「Canopus」队的“TiDB 计算微服务”项目等等……还有太多项目就不一一列举了，大家可以通过点击该[链接](https://asktug.com/t/topic/994153)了解全部决赛答辩项目。  \n\n由北京、上海、广州、成都、新加坡多城分布式联动的决赛答辩 & Demo Show 从下午 13:00 一直持续到深夜 20:30。虽然决赛时长将近 8 个小时，但是大家越看越兴奋。平时含蓄内敛的技术大佬们一旦介绍起自己的产品，就变身为滔滔不绝的演说家。\n\n最终，经过紧张评选，评委团共评出了 TiDB 产品组和应用的一、二、三等奖和最佳创意奖、公益贡献奖、技术趋势奖、Cloud 应用生态奖、最佳人气奖、最佳校园奖、用户之选奖。由于奖项角逐太激烈，有很多优秀项目遗憾落选，以下是全部获奖名单：\n\n![获奖名单.png](https://img1.www.pingcap.com/prod/_9c72ac9180.png)\n\n### 加冕时刻\n\n![产品组一等奖.png](https://img1.www.pingcap.com/prod/_83934100c4.png)\n<center>TiDB 产品组一等奖获奖团队</center>\n\n![应用组一等奖.png](https://img1.www.pingcap.com/prod/_aa35b79b2c.png)\n<center>应用组一等奖获奖团队</center>\n\n![产品组二等奖.png](https://img1.www.pingcap.com/prod/_dad30e1958.png)\n<center>TiDB 产品组二等奖获奖团队</center>\n\n![应用组二等奖.png](https://img1.www.pingcap.com/prod/_849b963110.png)\n<center>应用组二等奖获奖团队</center>\n\n![产品组三等奖.png](https://img1.www.pingcap.com/prod/_f80f9b1f99.png)\n<center>TiDB 产品组三等奖获奖团队</center>\n\n![产品组三等奖-2.png](https://img1.www.pingcap.com/prod/2_4e2d2b6231.png)\n<center>TiDB 产品组三等奖获奖团队</center>\n\n![应用组三等奖-1.png](https://img1.www.pingcap.com/prod/1_d659502042.png)\n<center>应用组三等奖获奖团队</center>\n\n![产品组最佳校园奖获奖团队.png](https://img1.www.pingcap.com/prod/_0410b64f46.png)\n<center>TiDB 产品组最佳校园奖获奖团队</center>\n\n![应用组最佳人气奖获奖团队.png](https://img1.www.pingcap.com/prod/_b564cf3f38.png)\n<center>应用组最佳人气奖获奖团队</center>\n\n![产品组最佳人气奖.png](https://img1.www.pingcap.com/prod/_b993c9aab3.png)\n<center>TiDB 产品组最佳人气奖</center>\n\n![应用组一等奖.png](https://img1.www.pingcap.com/prod/_aa35b79b2c.png)\n<center>应用组用户之选奖获奖团队</center>\n\n本届参赛项目再一次打开了我们对于 TiDB 想象力的界限。极客们丰富的想象力，会让你大开眼界，重拾对技术探索的激情。\nDemo Show 全程视频即将上线 b 站 [TiDB_Robot](https://space.bilibili.com/86485707/) 账号，敬请期待！\n\n特别感谢 PingCAP 数据平台产品负责人高斌、爱奇艺数据库服务负责人郭磊涛、PingCAP 联合创始人兼 CTO  黄东旭、PingCAP Outbound PM 黄潇、TiDB Committer, Seaweedfs Contributor 李雨来、PingCAP 资深开发工程师刘聪、小米数据库工程师，TiDB Committer 刘子东、Kyligence 技术合伙人，Apache Kylin 社区 PMC 成员马洪宾、联易融副总裁沈旸、TiDB Cloud Ecosystem 研发负责人孙晓光、PingCAP 研发副总裁唐刘、GGV 纪源资本投资人王笛、PingCAP SQL 研发负责人王聪、华创资本管理合伙人吴海燕、积梦智能 CEO，GoCN 社区发起人谢孟军、PingCAP DM 研发负责人徐成选、PingCAP 产研顾问张东晖、 Morpheuslabs CEO Chuang Pei-Han 等老师认真负责的评审。  \n\n赛后，我们还将采访优秀项目赛队，为大家深入介绍他们的项目设计思路、实现过程以及未来工作方向，希望带给大家一些启发。敬请期待！  \n\n最后，感谢华创资本、云启资本、GGV、初心资本、AWS、GCP、伊克罗德等赞助商和合作伙伴对赛事的大力支持，也感谢志愿者们的奉献！TiDB Hackathon 2023 ，我们再见！  \n\n![赞助商.png](https://img1.www.pingcap.com/prod/_b008ab31d6.png)\n\n","author":"PingCAP","category":3,"customUrl":"hardcore-ideas-in-tidb-hackathon-2022","fillInMethod":"writeDirectly","id":436,"summary":"TiDB Hackathon 2022 决赛刚好在 1024 程序员节前夜完美收官，48 小时的 Happy Hacking，参赛项目有趣、有料，精彩不断！","tags":["TiDB Hackathon 2022"],"title":"鏖战 48 小时，TiDB Hackathon 都诞生了哪些硬核创意？"}}]},{"id":"Blogs_431","title":"老朋友新朋友，抱紧“大腿”，冲击第一名！ | TiDB Hackathon 选手访谈","tags":["TiDB Hackathon 2022"],"category":{"name":"社区动态"},"summary":"TiDB Hackathon 2022 已经进入倒计时，距离决赛日还有不到一周时间，今年由于赛制的变化，初赛提前到了赛前（10 月 17 日），你已经准备好自己项目的 RFC 了吗？","body":"目前，[TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 已经进入倒计时，距离决赛日还有不到一周时间，今年由于赛制的变化，初赛提前到了赛前（10 月 17 日），你已经准备好自己项目的 RFC 了吗？如果还没有，请注意 10 月 17 日是 RFC 收集最后截止日，如果还没有报名或准备 RFC 的小伙伴，要抓紧时间啦！\n\n为了帮助大家更从容地参加比赛，TiDB 社区本期访谈中采访了三位 Hackathon 参赛选手，他们有第一次参加的，也有参加 2 届的选手，希望通过访谈为大家分享一下他们的参赛经验。已经报名参加本届 Hackathon 的选手或是对 Hackathon 感兴趣的小伙们，值得一看！\n\n## 俞平\n\n第一位选手是来自 P 社内核组的俞平同学，他至今有两次 Hackathon 的经验，前年作为技术小组帮助选手解决问题，去年首次下场参赛。今年更是信心满满，决定向奖项发起冲击！\n\n以下为俞平同学的访谈记录：\n\n**Q 去年 TiDB Hackathon 中的参赛项目是什么**？\n\n**俞平**：去年我报名了生态组，是和两位社区的小伙们一起组队参加的。他们日常工作中就在用 TiDB 支持业务，遇到的最大问题是在用 TiCDC 做同步时，如果一个单表特别大的话，现有 TiCDC 的设计会有一些限制。所以，我们就把优化这个问题作为参赛题目，希望降低一些这个问题的限制。最后虽然离理想状态还有些距离，但也算有些效果，重在参与嘛。\n\n**Q 你是如何找到项目 idea 灵感的**？\n\n**俞平**：在 Hackathon 比赛中主要有两类 idea：一种是有趣好玩的，也是我比较喜欢的。将那种脑洞比较大，甚至有些不太正经的的想法带入项目中，比如去年用 minecraft 来展示 Chaos Mesh 运作方式的项目，前年用 VR 飞机驾驶舱的方式来展现 TiDB 运维的项目，我觉得这些 idea 真的非常棒；另一种就是像我们一样，在平时使用 TiDB 的过程中觉得有什么地方是可以优化提升的，那就可以将这个作为 idea 来参加比赛。\n\n**Q 在你眼中，这些年 TiDB Hackathon 有哪些变化**？\n\n**俞平**：我觉得 TiDB Hackathon 的内核其实一直没有改变过，借这个大赛大家可以有一个展示自己创意的机会。从比赛上来说，奖品越来越丰富，组织越来越完善了，去年设置了 4 个赛道，大家可以在不同赛道里比赛，能更好地找到自己的 idea。今年虽然改为 2 个赛道，但类别感觉更清晰了。产品赛道更偏向 TiDB 的内核，应用赛道更偏向业务场景，从 TiDB 的角度看，这两个方面都是紧密结合的领域。另外，今年我发现主办方从赛制上降低了了初赛的难度，大家可能终于可以不那么卷了。\n\n**Q 今年已经参赛了吗**？\n\n**俞平**：今年有一位大佬邀请我抱他的“大腿”，于是我和其他几位小伙伴就毫不犹豫地与大佬一起组队报名了。我们的队名叫“摸鱼就好”，项目应该属于产品组。\n\n**Q 开始写 RFC 了吗？有没有什么小技巧分享**？\n\n**俞平**：今年不让抢跑，所以还没有提交 RFC。写 RFC 有点类似于写设计文档，我的经验是主要由三个部分组成：首先要讲清楚我要做一个什么东西，这个东西长什么样子，它要解决什么问题，它的适用场景是什么，甚至可能它不解决什么样的问题。从这些方面把项目进行清晰的定义，这是比较重要的第一步；接下来就是介绍采取什么技术方案，曾经考虑过的备选方案是哪些，做了哪些权衡最终选择了当前技术方案；最后，还要加上做过哪些测试与验证。如果大家不知道怎么写，其实也可以查看一下往期的 RFC 是怎么写的，网上应该都可以查到。\n\nRFC 毕竟是文字的东西，在答辩里可以再加一些文字之外的东西，比如我这个 idea 产生的背景是什么，我们在过程中是怎么讨论的，有一个怎么样的心路历程，这样可以让评委更好理解，印象更深刻。\n\n**Q 今年有什么期待**？\n\n**俞平**：大佬说我们今年的项目冲击第一名还是有希望的，我尽力而为吧。\n\n## 夏力维\n\n下面这位选手是十年全栈工程师夏力维，前齐书在线即时文档工具早期工程师，多年创业，历经协同文档、O2O、美妆、工厂自动化运营脚本，堪称全能型选手。\n\n以下为夏力维同学的访谈记录：\n\n**Q 你都参加过哪些比赛类活动**？\n\n**夏力维**：自 2011 年参加“硅谷-上海黑客马拉松”后，我开始在技术社区活动较为积极参与。曾参与过由 AVOSCloud Hackathon 和 Autodesk 组织的 AEC Hackathon，并获得前三。在新技术体验和使用中，感受到了来自前沿科技公司对于新技术的普及与推广力度。在这个时代，没有那么商业与限制，更多是对于更好的技术与业务运用的结合，能看到平时看不到的技术应用和视野拓展。\n\n**Q TiDB Hackathon 有哪些方面吸引你**？\n\n**夏力维**：我很早就通过上海的 GDG 技术社区听说过 TiDB 的使命，我自己是 Bret Taylor 的忠实追随者，在数据结构部分有继承 FriendFeed 思想的 DB 方案产品，在面对 TiDB 时，期待有更好的结合。\n\n**Q 今年从什么渠道了解到 Hackathon？你选择哪个赛道**？\n\n**夏力维**：有一个友人推荐了项目，她老公是《剑指 Offer》的作者，也非常推荐 TiDB 的活动。我选择了应用组赛道，倒不是觉得这个赛道压力小，而是觉得这个赛道能够验证数据管理的过程中，其实是可以实现更高扩容性能的。今年也期待看到更多可以落地的应用产品，并且让很多人看到并能参与进来。\n\n**Q 队伍名字是什么？参赛项目是什么**？\n\n**夏力维**：我的队名叫 HOTPOOR，一个人的全栈工程师队伍。我的项目是像做 PPT 一样做网站建设，并且直接可用。而不是仅仅像 Figma 做设计，或者 Axure 做原型，对标产品 Gamma.app ，但要更自由。\n\n## 杜志刚\n\n最后这位选手是在软件开发行业拥有 20 年的工作经验的杜志刚。在中国 10 年，主要做编码工作；在日本 10 年，主要也是做编码工作，不同的是能吃到寿司和纳豆:P  。从 2018 年开始通过 Kubecon 了解到 TiDB，从此一发不可收拾，沉醉于 TiDB 的学习上。目前已经加入 P 社，从事日本本地的技术支持工作。\n\n**Q 去年你带来的是什么项目？能给其他选手分享一下提 idea 的经验或灵感吗**？\n\n**杜志刚**：去年我们带来了 [Ti-Click](/blog/ti-click) 的社区雏形，希望能让应用开发者用户更多地了解 TiDB，更好地使用 TiDB。PingCAP 目前在应用开发者方面做得还不够，包括 MySQL 生态圈的各种库和框架对 TiDB 的最佳适配还不够，比如 TiDB 可以更好地横向扩展，那么连接池也应该有所调整以便能用上新结点。课题很多，希望更多的应用开发者参加到 Hackathon 里来，从应用开发者角度出发，把 TiDB 玩得更好。\n\n**Q 在你眼中， 这些年来 TiDB Hackathon 有哪些变化**？\n\n**杜志刚**：今年的变化感觉比较大，从赛制上讲这次更加公平，不抢跑，限定 2 天编码，更接近极客精神；最吸引我的地方是可以感受到 TiDB 热情的社区氛围，观摩各路大神的精彩成果。\n\n同时，今年的赛道设置为 TiDB 产品组和应用组。我觉得应用组的增设非常好，因为我应用开发经验更多，更适合在这个领域施展。期待 TiDB“出圈” ，产品组固然很好很强大，但是局限于产品组来的人估计也都是老面孔了。应用组可以吸引更多的开发者来关注 TiDB，让 TiDB 的生态变得更强。\n\n**Q 目前是否已经组队？项目是什么方向**？\n\n杜志刚：我们的队伍还是叫 Ti 可立刻，打算继续从应用开发的角度或 DBA 的角度来寻找 idea，我们队的目标是面向 TiDB 的应用开发者服务。我们会根据主流编程语言推出一系列项目模版，内置应用程序使用 TiDB 的最佳实践，让应用程序最佳化使用 TiDB，少走弯路。同时我们还和 TiDB Cloud 一键集成，并且也针对应用开发者的本地开发需求和 CI 环境，提供 gitpod 和 docker-compose 方案，使得应用开发者省去配置这些周边环境的工作，集中精力实现自己的业务逻辑。\n\n**Q 作为老选手，你们 RFC 准备应该也比较有经验，有没有一些小技巧可以分享给今年的小伙伴们呢**？\n\n**杜志刚**：其实谈不上什么经验。不过我想它类似工作报告，只要表达清楚为什么做/要做什么/怎么做就好了。\n\n**Q 对自己的项目在比赛中有什么期待**？\n\n**杜志刚**：期待以此为契机，让 TiDB 的应用开发生态发展得更好。\n\n**Q 有没有一些其他参赛经验想分享给其他小伙伴的**？\n\n**杜志刚**：我仅参加过一年，经验不多。我自己想的是，好好享受社区的火热气氛，燃烧自己的热情，享受 Hackathon 的这个过程。\n\n通过三位选手的分享，想必也为大家提供了一些参赛经验和项目思路。总结一下，项目创意可以从平时遇到的问题出发，最好能做得好玩有趣一些。写 RFC 关键要写清楚项目的目标、解决哪些问题、适用场景、技术方案以及验证测试 DEMO。**关于如何设计 RFC，大家也可以看一下官方模板**：https://asktug.com/t/topic/903770\n\n最后，敲黑板说重点：**10 月 17 日是 RFC 收集最后截止日**，还没有报名或准备 RFC 的小伙伴要抓紧时间啦，赶上最后一班车~\n\n了解 [TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 更多详情，立即报名参加吧！","date":"2022-10-14","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"old-and-new-friends-in-tidb-hackathon","file":null,"relatedBlogs":[{"relatedBlog":{"body":"![hackathon 2022 kv.jpeg](https://img1.www.pingcap.com/prod/hackathon_2022_kv_000f450a54.jpeg)\n\n一年一度的 TiDB Hackathon 又来啦！\n\n[TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 主题为「**Possibility at Scale**」，9 月 13 日正式开启，线下决赛将在 2022 年 10 月 22 - 23 日举行。期待与你一起打破传统技术边界，突破固有思维局限，用 TiDB 释放创新的更多可能性。\n\n本届 TiDB Hackathon 将面向更广泛人群，分为**应用组**与 **TiDB 产品组**两大赛道。无论你是应用开发者、数据库开发者、数据库上下游生态从业人员，还是数据库使用者，都可以找到适合自己的方向，一起“玩转” TiDB。\n\nTiDB Hackathon 报名通道于 2022 年 9 月 13 日正式开启，**选手们可以自行组队参赛，通过初赛甄选后，将在现场完成 Coding 及决赛答辩，优胜队伍将获得奖金、技术和资源商的支持**。大赛评委阵容豪华，数据库领域资深专家、社区技术大牛、顶级投资人代表将对项目进行深度点评。此外，还有顶级投资人全程参与评选，让你的实力被更多人看到。\n\n**扫描下图二维码，立即报名参赛**，或前往 [TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 活动页报名。\n\n![报名参赛.jpeg](https://img1.www.pingcap.com/prod/_f7bfacf978.jpeg)\n\n从 2017 年到 2022 年，TiDB Hackathon 不断升级，吸引了全球 1000 + 技术爱好者参与，先后诞生了诸如 UDF 引擎、TiExec、TiMatch 等深受好评的硬核项目，也有 zh.md、TiDB 驾驶舱、pCloud 等新颖有趣的项目。同时，部分优秀项目还在海内外媒体平台获得了多重曝光，借助 TiDB 社区力量为项目提供更多生命力。\n\n在 TiDB Hackathon ，你可以尽情发挥想象力与创造力，全情投入，实现自己的 idea。我们希望你可以永葆对技术的热情与好奇心，在代码的世界中勇敢探索、一往无前。我们在 TiDB Hackathon 2022 等你，期待与你共赴这场技术盛宴！\n\n## 赛事亮点\n\n🌟 **奖金丰厚**\n\n大赛总奖金池高达 35 万元，奖项多达 10+ 个，涵盖各个方向，力求全方位挖掘各参赛项目的价值。\n\n🌟 **各路大神同台竞技**\n\n技术大神齐聚一堂，上演“神仙打架”，场面超燃。高手之间的巅峰对决，精彩纷呈，让人大开眼界。\n\n🌟 **高质量交流**\n\n数据领域知名专家、社区技术大牛担任大赛评委，对项目进行深入点评，还有顶级投资人全程参与评选，你将不止收获硬核的技术反馈，还会获得前瞻性启发。\n\n🌟 **优秀项目专题采访**\n\n大赛结束后，我们将对优秀项目进行专题采访，在海内外技术圈多重曝光，提升优秀项目的知名度，借助 TiDB 社区力量为项目提供更多生命力。\n\n## 丰厚奖金\n\n**奖金池 35 万元，10+ 奖项，20+ 获奖团队**\n\n![丰厚奖金.jpeg](https://img1.www.pingcap.com/prod/_d265519d19.jpeg)\n\n**神秘定制社区周边**\n\n![定制社区周边.jpeg](https://img1.www.pingcap.com/prod/_c6c05c4a61.jpeg)\n\n## 参赛对象\n\n不管你是数据库内核工程师、数据库生态上下游开发者，还是应用开发者，只要你有 idea，都可以报名参赛，一展你的风采！\n\n## 赛道设置\n\n**应用组**\n\n以体现 TiDB 产品价值为主，基于 TiDB 之上实现代码开源的产品、工具、应用等均可。部署方式上，更推荐基于 Cloud 构建 TiDB 相关应用。推荐领域：游戏、电商、金融科技、公益等。\n\n**TiDB 产品组**\n\n为 TiDB 内核产品以及 TiCDC、TiDB Lightning、TiUP 等周边工具的性能、稳定性、易用性或功能等各方面做出提升。\n\n## 赛程安排\n\n- 报名：即日起 - 10 月 17 日，开启报名\n\n- 组队：9 月 17 日，参加「非正式会谈 — 创意脑暴会」，获取项目灵感（详见下方介绍）\n\n- 线上初赛：报名后 -  10 月 17 日，提交 RFC 进入初赛环节\n\n- 名单公布：10 月 19 日，查看决赛入围名单\n\n- 现场 Coding & 决赛：10 月 22 日 - 10 月 23 日，现场 Coding & 决赛答辩\n\n![比赛日程.png](https://img1.www.pingcap.com/prod/_357da0cc3c.png)\n\n## 评委阵容\n\n数据库领域知名专家、社区技术大牛、顶级投资人代表等担当评委，还有顶级投资人全程坐镇，对比赛项目深入点评。\n\n![评委.png](https://img1.www.pingcap.com/prod/_db0a886a7b.png)\n\n<center>（评委按姓名首字母排序）</center>\n\n比赛有输赢，技术无高低。即便最终未能问鼎巅峰，朝着心之所向全力冲刺依旧是一段值得回忆的旅程。秉承不断突破和创造的黑客精神，来一场技术的狂欢盛宴吧。放码过来！\n\n## 创意脑暴会给你灵感\n\n**TiDB Hackathon 2022 非正式会谈 —— 创意脑暴会**来啦，这里有超多 idea，特邀东旭以及资深架构师们在线脑暴，给你超丰富项目灵感。9月17日 本周六 10:30-12:00（GTM+8），线上见～\n\n![创意脑暴.jpeg](https://img1.www.pingcap.com/prod/_a800efa48b.jpeg)\n\n## 合作伙伴\n\n![合作伙伴.png](https://img1.www.pingcap.com/prod/_c6b365d0d3.png)\n\n了解 [TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 更多精彩！\n\n","author":"PingCAP","category":3,"customUrl":"tidb-hackathon-2022-is-coming","fillInMethod":"writeDirectly","id":426,"summary":"一年一度的 TiDB Hackathon 又来啦！TiDB Hackathon 2022 主题为「Possibility at Scale」,9 月 13 日正式开启，线下决赛将在 2022 年 10 月 22 日 23 日举行。","tags":["TiDB Hackathon 2022"],"title":"TiDB Hackathon 2022丨总奖金池超 35 万！邀你唤醒代码世界的更多可能性！"}},{"relatedBlog":{"body":"![banner.jpeg](https://img1.www.pingcap.com/prod/banner_6e96e050b4.jpeg)\n\n一年一度黑客们的狂欢——[TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 报名已开启，万元奖金等你来拿，还有技术专家、顶级投资人全程坐镇，你的实力将被更多人看到。\n\nTiBD Hackathon 2022 ·「Possibility at Scale」，邀请你一起打破传统技术边界，突破固有思维局限，用 TiDB 释放创新的更多可能性。\n\n悄悄说：今年真的不卷，值得一试！\n\n两大赛道，任选：\n\n- 应用组：推荐噢，因为特别奖项更多！\n\n以体现 TiDB 产品价值为主，使用 TiDB 构建代码开源的产品、工具、应用等均可。部署方式上，更推荐基于 Cloud 构建 TiDB 相关应用。常见应用领域：游戏、电商、金融科技、公益等。\n\n- TiDB 产品组：延续传统，保持初心\n\n为 TiDB 内核产品以及 TiCDC、TiDB Lightning、TiUP 等周边工具的性能、稳定性、易用性或功能等各方面做出提升。\n\n扫描下方二维码立即报名参与！\n\n![报名.jpeg](https://img1.www.pingcap.com/prod/_3b43724e2f.jpeg)\n\n听说你想参加 TiDB Hackathon，却没有 idea？\n\n别担心，脑洞达人东旭和他的架构师朋友们在创意脑暴会上分享的项目 idea 都整理好啦，快来看看有没有你感兴趣的~（ps：搭配视频查看 idea 详细介绍，效果更佳哦~） \n\n**创意贡献嘉宾**\n\n黄东旭 PingCAP 联合创始人兼 CTO\n\n姚维 PingCAP 全球社区生态负责人\n\n张兴晔 多点系统架构师\n\nCheng Chen PingCAP Product Manager\n\n[脑暴会视频](https://www.bilibili.com/video/BV1yG411u7N9/)\n\n## 应用组\n\n![应用组.jpeg](https://img1.www.pingcap.com/prod/_e769b14808.jpeg)\n\n今年应用组的决赛参赛项目仅要求是 demo 级别的，例如以下项目示例：\n\n- OSS Insight：https://ossinsight.io/\n\n这是一个基于 TiDB 实现的，数十亿 GitHub events 数据构建的洞察工具。只要你会写 SQL，就可以基于 Docusaurus、Apache ECharts 构建一个强大、酷炫的数据洞察工具。\n\n- TiDB & Snowflake Demo：https://tidb-snowflake-e-commerce-demo.vercel.app/\n\n这是一个基于 TiDB 和 Snowflake 构建的电子商务系统，该系统使用了 TiDB 强大的实时 HTAP 能力和 Snowflake 的离线分析能力，来处理系统中大量的数据。\n\n- Ti-Click：http://ide.ti-click.com/\n\n这是 TiDB Hackathon 2021 的 20 强项目之一，项目通过在线 IDE 的方式，快速搭建基于 TiDB 的 Example App 的开发和在线编译的实验室，可帮助开发者快速学习 TiDB。\n\n- Bookshop\n\n这是一个基于 TiDB 搭建的在线书店应用，你可以通过它来学习如何导入表结构和数据，以及如何基于这些数据来编写 SQL。\n\n[这篇文章](https://docs.pingcap.com/zh/tidb/stable/dev-guide-bookshop-schema-design)也以 Bookshop 应用的数据表结构和数据为基础来编写示例 SQL，为你介绍如何导入该应用的表结构和数据，以及其数据表结构的定义。\n\n- Gitpod\n\n对于 TiDB 初学者，我们基于 Gitpod，提供了一个云原生开发环境的使用帮助，你可以直接从你的浏览器或桌面 IDE 启动一个远程的 TiDB 开发环境，快速体验 TiDB 的能力。我们编写了全新的 TiDB 开发者文档，这份文档可以帮助应用开发者，在最短时间内上手 TiDB。\n\nTiDB 开发者文档：https://docs.pingcap.com/zh/tidb/stable/dev-guide-overview\n\n## TiDB 产品组\n\n![TiDB 产品组.jpeg](https://img1.www.pingcap.com/prod/Ti_DB_77ad779a1c.jpeg)\n\n## 彩蛋组\n\n彩蛋组不可更改 TiDB/TiKV 源码，仅可使用插件方式进行 Hack。\n\n![彩蛋组.jpeg](https://img1.www.pingcap.com/prod/_f6b386df89.jpeg)\n\n希望可以给你一些方向与灵感！更多项目 idea 也可以来 [Hackathon 2022 创意库](https://asktug.com/t/topic/933124)找灵感。\n\n看到这么多 idea，你是否跃跃欲试了呢？\n\n热爱编程，勇于探索，就能参赛\n\n你离万元大奖只有一个报名的距离~\n\n了解 [TiDB Hackathon 2022 ](https://tidb.net/events/hackathon2022)更多详情！","author":"PingCAP","category":3,"customUrl":"hackathon-idea-list-for-reference","fillInMethod":"writeDirectly","id":427,"summary":"一年一度黑客们的狂欢——TiDB Hackathon 2022 报名已开启，万元奖金等你来拿，还有技术专家、顶级投资人全程坐镇，你的实力将被更多人看到。","tags":["TiDB Hackathon 2022"],"title":"Hackathon idea 清单出炉，总有一款适合你"}},{"relatedBlog":{"body":"[TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 正在火热报名中，截止目前已经收到 230+ 位参赛者报名，组队近 60 组。想必各位选手已经摩拳擦掌，开始准备自己项目的 RFC 了。\n\n在等待比赛日的这段时间，**TiDB 社区采访了多位 Hackathon 参赛选手，通过访谈为大家分享一下他们对 Hackathon 的理解和感悟，同时探讨开源给他们的个人生活和工作带来了哪些改变**。当然，作为老选手，也会有极其珍贵的参赛经验分享。已经报名参加本届 Hackathon 的选手或是对 Hackathon 感兴趣的小伙们，赶紧看过来！\n\n今天与大家见面的参赛选手是**目前在南京邮电大学读研三的陆涣冰同学**，其实他的专业方向本来是卫星通信，但内心却十分热爱计算机底层技术，业余时间基本 all in 在开源分布式数据库上。\n\n## 本期嘉宾：陆涣冰\n\n> 涣冰同学与 TiDB Hackathon 的缘分源自研一那年：当时看到比赛的信息后就非常想参加，但苦于自己技术水平不够，同时也没找到人组队，差点错过。幸好当时社区的运营同学给了很多鼓励，并说明个人参赛也是规则允许的，这才被引入了 Hackathon 这条路。之后涣冰就一发不可收拾，研一、研二、研三接连三届都参加了 TiDB Hackathon。\n\n以下为采访记录：\n\n**Q 为什么选择单刷的方式参加 TiDB Hackathon**？  \n\n**陆涣冰**：其实单刷主要是因为自己想做的一些东西，对于很多人而言比较抽象，比较困难。举例来说，我去年做的题目就是用 eBPF 去加速 TiDB 的底层存储路径。这个项目可能需要比较多的底层知识的铺垫，当时问了一圈发现没人对此感兴趣，最终还是自己一个人参赛。其实拿不拿奖无所谓，玩得开心就好。**参加 TiDB Hackathon 帮我整个研究生的三年开了一个头，之后我又参加了各种开源的比赛**，比如阿里的天池数据库大赛、open Euler 高校开发者大赛等等。  \n\n我能开启这条路要感谢两个人。第一个人就是当时的社区运营 yanqing，她对我有某种程度上的知遇之恩，如果没有她我后面的这些经历应该都不存在。第二个人是当时在 P 社实习时的 mentor 施闻轩，他对于我在技术上理解的影响是比较深远。\n\n**Q 最早是在什么时候对编程感兴趣的**？  \n\n**陆涣冰**：我本科的专业是网络工程，研究生的专业是信息网络，乍一听起来好像都是计算机学科的分支。那时候其实走了一段弯路，当时整个人掉进了安全的圈里，觉得黑客好酷，什么病毒、逆向都觉得非常酷。**但是在深入学习了安全一段时间，就感觉做安全好玩归好玩，但是真的要把这个当做职业，心里感觉还是缺了一点什么**。在 2019 年 2 月 1 日，那天是我的生日，所以我印象特别清晰，在跟朋友聊天时，我问自己以后确定要做安全了吗？还是想更深入地写代码？因为当时身边很多做安全的朋友只是敲敲命令行跑跑脚本，感觉中国的安全确实青黄不接，厉害的确实非常厉害，但菜的实在是太菜了。那时候我这方面的技能，不谦虚地讲可以说是炉火纯青了，但是写代码的功底还是一塌糊涂。   \n\n和来自美团、百度的一些圈内朋友聊了聊，他们建议可以考虑一下前端业务应用开发或编译器、数据库、操作系统等更底层的开发。当时也是年少无知，就说要不学个数据库吧。于是从那天就一直学到了今天，然后就发现**一入数据库深似海，这里面的东西实在是太庞大了。不仅要有系统知识，还要涉及编译器的知识，分布式的知识**。伴随着这个学习过程，自己编码的水平也逐渐上来了。  \n \n说实话，身边除了自己，再也找不到第二个人做软件开发或者数据库开发。平时在学校的教研室里基本清一色都是前端开发，这三年来，就我一个人坐电脑前自学了三年。在接触到 PingCAP 时，有一种突然找到组织的感觉。\n\n**Q 开源带来的乐趣或收益是什么**？  \n\n**陆涣冰**：学习数据库的时候其实已经对开源有了一定的认知，基本上 99% 的知识全部来自于开源，无论对操作系统还是对计算机体系的理解，基本都是构建于开源软件之上的。第一次接触 Linux，我发现这不就是我想要的操作系统？**大家都能改、都能用，改完还能 push 进项目里，开放给别人用。某种程度上开源可以汇聚全人类的智慧去做一些事情**。当然开源协作也会有很多问题，比如贡献的代码好不好，有没有漏洞，能不能和别人达成一致协商等等。有些项目写一半甚至不写了，开发者跑了，撂挑子了，这都很常见。包括开源项目的商业化，哪些拿过来可以做出自己的东西，哪些可以二次开发拿去卖，哪些行为是违规的，都需要开源参与者去考虑。  \n\n但那时我还只是开源的使用者，到了读研之后，借由数据库才慢慢把手伸得更远一点，开始把自己的代码贡献给别人。\n\n**Q TiDB Hackathon 与其他比赛在体验上有什么区别**？  \n\n**陆涣冰**：那实在是太多了。**第一还是人**，PingCAP 这边的小助手实在是太热情了，工作做得非常好。我参加了三年，基本上会和每一届的小助手成为朋友。第二点是 Hackathon 的所有项目都构建在 TiDB 之上，**TiDB 有非常多的文档，有对于内核、原理的解读，我认为这点在众多参与过的比赛、项目中可以说是最优秀的**。这些工作大大减少了开发者想深入了解 TiDB 所需要的时间。举个例子，我在参加某个比赛的时候，他们就干巴巴地放出赛题以及代码框架，剩下就全部交给你自己了，非常不容易上手，新手非常难做。而 TiDB 的源码与文档可以帮助开发者在比赛中减少非常多的时间。  \n \n也说说不足，我已经参加了三届，感觉其实有很多 idea 都是前面已经做过的，总会被不断掏出来翻新。建议官方可以把过往的项目整理出来，避免后面的重复。去年有人说 Hackathon 是不是已经没有太多 idea 可以提了，其实我认为随着 TiDB 的发展，加了很多新的 feature 后 TiDB 已经变得越来越复杂，大家原本对于 TiDB 3.0、4.0 的理解放在 6.0 上可能就不适用了，需要再花大精力去做一些有比较有意思的东西。但这可能就需要花很长时间读源码，深入了解 6.0 的设计，这对于外面想参加的人来说就非常困难，所以他们才会说能做的变少了。其实不是变少了，是难度变得太高了，花费的时间成本更高了。\n\n**Q 作为老选手，能不能给新选手分享一下 Hackathon 创意的灵感**？  \n\n**陆涣冰**：其实我有一个想法，有一天我们能把编译器、数据库、操作系统打通，把数据库直接放在与操作系统一样的等级上去。我的所有灵感一直都是围绕这个愿望出发的，**不要为了比赛而想点子，而是为了做出自己理想中的那个数据库，让现在的数据库朝着理想中数据库出发，看看还有什么缺的地方，一步一步实现**。  \n \n我今年的思路其实和东旭之前的想法很相似，TiDB 后端现在存储引擎用的是 target 编码，先前计算机如果出了问题，都可以通过添加一层中间件或者中间层来解决。那我就想能不能添加这样一个中间层，把 TiDB 和 TiKV 解耦，让后面的存储引擎能够无缝切换。这是我今年想做的事情，但是不知道能不能做成功，做成什么样子。  \n \nLinux 内核进入 6.2 版本之后， Rust for Linux 基本上就能稳定了，**当 Rust 进入 Linux 内核之后，能与数据库更深层次的互动**。这个就是我讲的把操作系统与数据库放在同一个 level，其实一直在朝这个目标在走。\n\n**Q 今年是你第三次参加 TiDB Hackathon，你觉得这些年有哪些变化**？  \n\n**陆涣冰**：作为一名底层开发者，**TiDB Hackathon 最吸引我的就是比较硬核的技术，比如 TiDB 先进的存储引擎、高效的性能，它能勾起我们的好奇心，去发掘一下这个数据库到底牛在哪**。  \n\n如果是对于前端开发者而言，TiDB Hackathon 对他们的吸引力就是**借由 TiDB 能去开发一些有意思的应用**，比如说无缝切换，比如更 native 的云原生基础组件，甚至替换 Kubernetes 里的某些功能等等。  \n \n我看到今年的赛制发生了一些变化，比如去年大多数比赛环节都安排在 48 小时里，初赛、决赛答辩，时间安排得满满当当。但今年主办方把初赛提前了，这能让选手们准备得更充分。参加 TiDB Hackathon 的大部分选手都是有工作经验的，或者是有 TiDB 使用经验的。他们对于这个数据库有着非常深的理解，可以借由 Hackathon 的机会把一些 actions 提前给做了。**但是对于外面的学生或者不是太熟悉 TiDB 架构的人而言，比赛周期的延长就非常有意义了**，他们能够有更充足的时间去阅读源码或者阅读文章，加深理解，能把 demo 做得更好一些。我第一届参赛时连 demo 都没有，根本来不及做。   \n\n另外，其实这些年我发现身边做底层开发的小伙伴虽然越来越多，但仍旧是杯水车薪。更多的人还是应用开发者，他们关心如何用数据库，而不是开发数据库，所以应用开发这个赛道的增加就很有意义了。应用开发者可以尽可能发挥，用这个数据库做出一些非常有意思的应用，展现出 TiDB 的更多可能性。\n\n**Q 参赛经验分享**  \n\n**陆涣冰**：想 idea 的时候千万不能闭门造车，要集思广益，收集一下已有的 RFC 或者 AskTUG 论坛里的一些问题，看一看 TiDB 的痛点在哪儿；再从评委的角度去想一想，是不是能第一时间 get 到你的想法。  \n\n我其实还没正式开始写 RFC，我的习惯是先把想法写在纸上，确定好了再腾到电脑上。**写 RFC 首当其冲是要表明你的目的，做这个东西是为了解决什么问题；其次描述一下项目的背景，让评委能明白这个项目的定位是在 TiDB 的哪一个技术分支里面；除此之外，要把图画好，这样才能讲好你的故事**。我第一次 demo 都没做出来，所以答辩的结果也就不尽如人意。第二次答辩确确实实把这个东西做出来了，做得是不是完美其实没有关系，大部分选手时间都一样紧张，关键在于能把你想做的事情、要做的事情、已经做过的事情讲明白就 OK 了。至于什么花里胡哨的画图、图表、效果，都是锦上添花的东西。\n\n关于如何设计 RFC ，可以参考这里：https://asktug.com/t/topic/903770\n\n我从本科到现在，参加了百余场比赛，而且每一场都是单刷。其实参加这些比赛的初衷是想把技术学好，想能为别人再做点什么事情，能做出来一些更实用的东西当然最好，不会太过于关注奖品、名次这些事情，更多还是关注于自己的项目和想法有没有实现。即便没有得到评委的认可，也是自己花时间和精力做出来的，这些写过的代码，对于自己的提升是 100% 是有帮助的。\n\n💡 看过涣冰的经历，你心动了吗？了解 [TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 更多详情，立即报名参加吧！","author":"PingCAP","category":3,"customUrl":"participated-in-hackathon-3-times-alone","fillInMethod":"writeDirectly","id":429,"summary":"在等待比赛日的这段时间，TiDB 社区采访了多维 Hackathon 参赛选手，通过访谈为大家分享一下他们对 Hackathon 的理解和感悟，同时探讨开源给他们的个人生活和工作带来了哪些改变。","tags":["TiDB Hackathon 2022"],"title":"单刷 3 届 Hackathon，朝着理想中的数据库出发丨TiDB Hackathon 选手访谈"}}]},{"id":"Blogs_429","title":"单刷 3 届 Hackathon，朝着理想中的数据库出发丨TiDB Hackathon 选手访谈","tags":["TiDB Hackathon 2022"],"category":{"name":"社区动态"},"summary":"在等待比赛日的这段时间，TiDB 社区采访了多维 Hackathon 参赛选手，通过访谈为大家分享一下他们对 Hackathon 的理解和感悟，同时探讨开源给他们的个人生活和工作带来了哪些改变。","body":"[TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 正在火热报名中，截止目前已经收到 230+ 位参赛者报名，组队近 60 组。想必各位选手已经摩拳擦掌，开始准备自己项目的 RFC 了。\n\n在等待比赛日的这段时间，**TiDB 社区采访了多位 Hackathon 参赛选手，通过访谈为大家分享一下他们对 Hackathon 的理解和感悟，同时探讨开源给他们的个人生活和工作带来了哪些改变**。当然，作为老选手，也会有极其珍贵的参赛经验分享。已经报名参加本届 Hackathon 的选手或是对 Hackathon 感兴趣的小伙们，赶紧看过来！\n\n今天与大家见面的参赛选手是**目前在南京邮电大学读研三的陆涣冰同学**，其实他的专业方向本来是卫星通信，但内心却十分热爱计算机底层技术，业余时间基本 all in 在开源分布式数据库上。\n\n## 本期嘉宾：陆涣冰\n\n> 涣冰同学与 TiDB Hackathon 的缘分源自研一那年：当时看到比赛的信息后就非常想参加，但苦于自己技术水平不够，同时也没找到人组队，差点错过。幸好当时社区的运营同学给了很多鼓励，并说明个人参赛也是规则允许的，这才被引入了 Hackathon 这条路。之后涣冰就一发不可收拾，研一、研二、研三接连三届都参加了 TiDB Hackathon。\n\n以下为采访记录：\n\n**Q 为什么选择单刷的方式参加 TiDB Hackathon**？  \n\n**陆涣冰**：其实单刷主要是因为自己想做的一些东西，对于很多人而言比较抽象，比较困难。举例来说，我去年做的题目就是用 eBPF 去加速 TiDB 的底层存储路径。这个项目可能需要比较多的底层知识的铺垫，当时问了一圈发现没人对此感兴趣，最终还是自己一个人参赛。其实拿不拿奖无所谓，玩得开心就好。**参加 TiDB Hackathon 帮我整个研究生的三年开了一个头，之后我又参加了各种开源的比赛**，比如阿里的天池数据库大赛、open Euler 高校开发者大赛等等。  \n\n我能开启这条路要感谢两个人。第一个人就是当时的社区运营 yanqing，她对我有某种程度上的知遇之恩，如果没有她我后面的这些经历应该都不存在。第二个人是当时在 P 社实习时的 mentor 施闻轩，他对于我在技术上理解的影响是比较深远。\n\n**Q 最早是在什么时候对编程感兴趣的**？  \n\n**陆涣冰**：我本科的专业是网络工程，研究生的专业是信息网络，乍一听起来好像都是计算机学科的分支。那时候其实走了一段弯路，当时整个人掉进了安全的圈里，觉得黑客好酷，什么病毒、逆向都觉得非常酷。**但是在深入学习了安全一段时间，就感觉做安全好玩归好玩，但是真的要把这个当做职业，心里感觉还是缺了一点什么**。在 2019 年 2 月 1 日，那天是我的生日，所以我印象特别清晰，在跟朋友聊天时，我问自己以后确定要做安全了吗？还是想更深入地写代码？因为当时身边很多做安全的朋友只是敲敲命令行跑跑脚本，感觉中国的安全确实青黄不接，厉害的确实非常厉害，但菜的实在是太菜了。那时候我这方面的技能，不谦虚地讲可以说是炉火纯青了，但是写代码的功底还是一塌糊涂。   \n\n和来自美团、百度的一些圈内朋友聊了聊，他们建议可以考虑一下前端业务应用开发或编译器、数据库、操作系统等更底层的开发。当时也是年少无知，就说要不学个数据库吧。于是从那天就一直学到了今天，然后就发现**一入数据库深似海，这里面的东西实在是太庞大了。不仅要有系统知识，还要涉及编译器的知识，分布式的知识**。伴随着这个学习过程，自己编码的水平也逐渐上来了。  \n \n说实话，身边除了自己，再也找不到第二个人做软件开发或者数据库开发。平时在学校的教研室里基本清一色都是前端开发，这三年来，就我一个人坐电脑前自学了三年。在接触到 PingCAP 时，有一种突然找到组织的感觉。\n\n**Q 开源带来的乐趣或收益是什么**？  \n\n**陆涣冰**：学习数据库的时候其实已经对开源有了一定的认知，基本上 99% 的知识全部来自于开源，无论对操作系统还是对计算机体系的理解，基本都是构建于开源软件之上的。第一次接触 Linux，我发现这不就是我想要的操作系统？**大家都能改、都能用，改完还能 push 进项目里，开放给别人用。某种程度上开源可以汇聚全人类的智慧去做一些事情**。当然开源协作也会有很多问题，比如贡献的代码好不好，有没有漏洞，能不能和别人达成一致协商等等。有些项目写一半甚至不写了，开发者跑了，撂挑子了，这都很常见。包括开源项目的商业化，哪些拿过来可以做出自己的东西，哪些可以二次开发拿去卖，哪些行为是违规的，都需要开源参与者去考虑。  \n\n但那时我还只是开源的使用者，到了读研之后，借由数据库才慢慢把手伸得更远一点，开始把自己的代码贡献给别人。\n\n**Q TiDB Hackathon 与其他比赛在体验上有什么区别**？  \n\n**陆涣冰**：那实在是太多了。**第一还是人**，PingCAP 这边的小助手实在是太热情了，工作做得非常好。我参加了三年，基本上会和每一届的小助手成为朋友。第二点是 Hackathon 的所有项目都构建在 TiDB 之上，**TiDB 有非常多的文档，有对于内核、原理的解读，我认为这点在众多参与过的比赛、项目中可以说是最优秀的**。这些工作大大减少了开发者想深入了解 TiDB 所需要的时间。举个例子，我在参加某个比赛的时候，他们就干巴巴地放出赛题以及代码框架，剩下就全部交给你自己了，非常不容易上手，新手非常难做。而 TiDB 的源码与文档可以帮助开发者在比赛中减少非常多的时间。  \n \n也说说不足，我已经参加了三届，感觉其实有很多 idea 都是前面已经做过的，总会被不断掏出来翻新。建议官方可以把过往的项目整理出来，避免后面的重复。去年有人说 Hackathon 是不是已经没有太多 idea 可以提了，其实我认为随着 TiDB 的发展，加了很多新的 feature 后 TiDB 已经变得越来越复杂，大家原本对于 TiDB 3.0、4.0 的理解放在 6.0 上可能就不适用了，需要再花大精力去做一些有比较有意思的东西。但这可能就需要花很长时间读源码，深入了解 6.0 的设计，这对于外面想参加的人来说就非常困难，所以他们才会说能做的变少了。其实不是变少了，是难度变得太高了，花费的时间成本更高了。\n\n**Q 作为老选手，能不能给新选手分享一下 Hackathon 创意的灵感**？  \n\n**陆涣冰**：其实我有一个想法，有一天我们能把编译器、数据库、操作系统打通，把数据库直接放在与操作系统一样的等级上去。我的所有灵感一直都是围绕这个愿望出发的，**不要为了比赛而想点子，而是为了做出自己理想中的那个数据库，让现在的数据库朝着理想中数据库出发，看看还有什么缺的地方，一步一步实现**。  \n \n我今年的思路其实和东旭之前的想法很相似，TiDB 后端现在存储引擎用的是 target 编码，先前计算机如果出了问题，都可以通过添加一层中间件或者中间层来解决。那我就想能不能添加这样一个中间层，把 TiDB 和 TiKV 解耦，让后面的存储引擎能够无缝切换。这是我今年想做的事情，但是不知道能不能做成功，做成什么样子。  \n \nLinux 内核进入 6.2 版本之后， Rust for Linux 基本上就能稳定了，**当 Rust 进入 Linux 内核之后，能与数据库更深层次的互动**。这个就是我讲的把操作系统与数据库放在同一个 level，其实一直在朝这个目标在走。\n\n**Q 今年是你第三次参加 TiDB Hackathon，你觉得这些年有哪些变化**？  \n\n**陆涣冰**：作为一名底层开发者，**TiDB Hackathon 最吸引我的就是比较硬核的技术，比如 TiDB 先进的存储引擎、高效的性能，它能勾起我们的好奇心，去发掘一下这个数据库到底牛在哪**。  \n\n如果是对于前端开发者而言，TiDB Hackathon 对他们的吸引力就是**借由 TiDB 能去开发一些有意思的应用**，比如说无缝切换，比如更 native 的云原生基础组件，甚至替换 Kubernetes 里的某些功能等等。  \n \n我看到今年的赛制发生了一些变化，比如去年大多数比赛环节都安排在 48 小时里，初赛、决赛答辩，时间安排得满满当当。但今年主办方把初赛提前了，这能让选手们准备得更充分。参加 TiDB Hackathon 的大部分选手都是有工作经验的，或者是有 TiDB 使用经验的。他们对于这个数据库有着非常深的理解，可以借由 Hackathon 的机会把一些 actions 提前给做了。**但是对于外面的学生或者不是太熟悉 TiDB 架构的人而言，比赛周期的延长就非常有意义了**，他们能够有更充足的时间去阅读源码或者阅读文章，加深理解，能把 demo 做得更好一些。我第一届参赛时连 demo 都没有，根本来不及做。   \n\n另外，其实这些年我发现身边做底层开发的小伙伴虽然越来越多，但仍旧是杯水车薪。更多的人还是应用开发者，他们关心如何用数据库，而不是开发数据库，所以应用开发这个赛道的增加就很有意义了。应用开发者可以尽可能发挥，用这个数据库做出一些非常有意思的应用，展现出 TiDB 的更多可能性。\n\n**Q 参赛经验分享**  \n\n**陆涣冰**：想 idea 的时候千万不能闭门造车，要集思广益，收集一下已有的 RFC 或者 AskTUG 论坛里的一些问题，看一看 TiDB 的痛点在哪儿；再从评委的角度去想一想，是不是能第一时间 get 到你的想法。  \n\n我其实还没正式开始写 RFC，我的习惯是先把想法写在纸上，确定好了再腾到电脑上。**写 RFC 首当其冲是要表明你的目的，做这个东西是为了解决什么问题；其次描述一下项目的背景，让评委能明白这个项目的定位是在 TiDB 的哪一个技术分支里面；除此之外，要把图画好，这样才能讲好你的故事**。我第一次 demo 都没做出来，所以答辩的结果也就不尽如人意。第二次答辩确确实实把这个东西做出来了，做得是不是完美其实没有关系，大部分选手时间都一样紧张，关键在于能把你想做的事情、要做的事情、已经做过的事情讲明白就 OK 了。至于什么花里胡哨的画图、图表、效果，都是锦上添花的东西。\n\n关于如何设计 RFC ，可以参考这里：https://asktug.com/t/topic/903770\n\n我从本科到现在，参加了百余场比赛，而且每一场都是单刷。其实参加这些比赛的初衷是想把技术学好，想能为别人再做点什么事情，能做出来一些更实用的东西当然最好，不会太过于关注奖品、名次这些事情，更多还是关注于自己的项目和想法有没有实现。即便没有得到评委的认可，也是自己花时间和精力做出来的，这些写过的代码，对于自己的提升是 100% 是有帮助的。\n\n💡 看过涣冰的经历，你心动了吗？了解 [TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 更多详情，立即报名参加吧！","date":"2022-10-11","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"participated-in-hackathon-3-times-alone","file":null,"relatedBlogs":[{"relatedBlog":{"body":"![hackathon 2022 kv.jpeg](https://img1.www.pingcap.com/prod/hackathon_2022_kv_000f450a54.jpeg)\n\n一年一度的 TiDB Hackathon 又来啦！\n\n[TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 主题为「**Possibility at Scale**」，9 月 13 日正式开启，线下决赛将在 2022 年 10 月 22 - 23 日举行。期待与你一起打破传统技术边界，突破固有思维局限，用 TiDB 释放创新的更多可能性。\n\n本届 TiDB Hackathon 将面向更广泛人群，分为**应用组**与 **TiDB 产品组**两大赛道。无论你是应用开发者、数据库开发者、数据库上下游生态从业人员，还是数据库使用者，都可以找到适合自己的方向，一起“玩转” TiDB。\n\nTiDB Hackathon 报名通道于 2022 年 9 月 13 日正式开启，**选手们可以自行组队参赛，通过初赛甄选后，将在现场完成 Coding 及决赛答辩，优胜队伍将获得奖金、技术和资源商的支持**。大赛评委阵容豪华，数据库领域资深专家、社区技术大牛、顶级投资人代表将对项目进行深度点评。此外，还有顶级投资人全程参与评选，让你的实力被更多人看到。\n\n**扫描下图二维码，立即报名参赛**，或前往 [TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 活动页报名。\n\n![报名参赛.jpeg](https://img1.www.pingcap.com/prod/_f7bfacf978.jpeg)\n\n从 2017 年到 2022 年，TiDB Hackathon 不断升级，吸引了全球 1000 + 技术爱好者参与，先后诞生了诸如 UDF 引擎、TiExec、TiMatch 等深受好评的硬核项目，也有 zh.md、TiDB 驾驶舱、pCloud 等新颖有趣的项目。同时，部分优秀项目还在海内外媒体平台获得了多重曝光，借助 TiDB 社区力量为项目提供更多生命力。\n\n在 TiDB Hackathon ，你可以尽情发挥想象力与创造力，全情投入，实现自己的 idea。我们希望你可以永葆对技术的热情与好奇心，在代码的世界中勇敢探索、一往无前。我们在 TiDB Hackathon 2022 等你，期待与你共赴这场技术盛宴！\n\n## 赛事亮点\n\n🌟 **奖金丰厚**\n\n大赛总奖金池高达 35 万元，奖项多达 10+ 个，涵盖各个方向，力求全方位挖掘各参赛项目的价值。\n\n🌟 **各路大神同台竞技**\n\n技术大神齐聚一堂，上演“神仙打架”，场面超燃。高手之间的巅峰对决，精彩纷呈，让人大开眼界。\n\n🌟 **高质量交流**\n\n数据领域知名专家、社区技术大牛担任大赛评委，对项目进行深入点评，还有顶级投资人全程参与评选，你将不止收获硬核的技术反馈，还会获得前瞻性启发。\n\n🌟 **优秀项目专题采访**\n\n大赛结束后，我们将对优秀项目进行专题采访，在海内外技术圈多重曝光，提升优秀项目的知名度，借助 TiDB 社区力量为项目提供更多生命力。\n\n## 丰厚奖金\n\n**奖金池 35 万元，10+ 奖项，20+ 获奖团队**\n\n![丰厚奖金.jpeg](https://img1.www.pingcap.com/prod/_d265519d19.jpeg)\n\n**神秘定制社区周边**\n\n![定制社区周边.jpeg](https://img1.www.pingcap.com/prod/_c6c05c4a61.jpeg)\n\n## 参赛对象\n\n不管你是数据库内核工程师、数据库生态上下游开发者，还是应用开发者，只要你有 idea，都可以报名参赛，一展你的风采！\n\n## 赛道设置\n\n**应用组**\n\n以体现 TiDB 产品价值为主，基于 TiDB 之上实现代码开源的产品、工具、应用等均可。部署方式上，更推荐基于 Cloud 构建 TiDB 相关应用。推荐领域：游戏、电商、金融科技、公益等。\n\n**TiDB 产品组**\n\n为 TiDB 内核产品以及 TiCDC、TiDB Lightning、TiUP 等周边工具的性能、稳定性、易用性或功能等各方面做出提升。\n\n## 赛程安排\n\n- 报名：即日起 - 10 月 17 日，开启报名\n\n- 组队：9 月 17 日，参加「非正式会谈 — 创意脑暴会」，获取项目灵感（详见下方介绍）\n\n- 线上初赛：报名后 -  10 月 17 日，提交 RFC 进入初赛环节\n\n- 名单公布：10 月 19 日，查看决赛入围名单\n\n- 现场 Coding & 决赛：10 月 22 日 - 10 月 23 日，现场 Coding & 决赛答辩\n\n![比赛日程.png](https://img1.www.pingcap.com/prod/_357da0cc3c.png)\n\n## 评委阵容\n\n数据库领域知名专家、社区技术大牛、顶级投资人代表等担当评委，还有顶级投资人全程坐镇，对比赛项目深入点评。\n\n![评委.png](https://img1.www.pingcap.com/prod/_db0a886a7b.png)\n\n<center>（评委按姓名首字母排序）</center>\n\n比赛有输赢，技术无高低。即便最终未能问鼎巅峰，朝着心之所向全力冲刺依旧是一段值得回忆的旅程。秉承不断突破和创造的黑客精神，来一场技术的狂欢盛宴吧。放码过来！\n\n## 创意脑暴会给你灵感\n\n**TiDB Hackathon 2022 非正式会谈 —— 创意脑暴会**来啦，这里有超多 idea，特邀东旭以及资深架构师们在线脑暴，给你超丰富项目灵感。9月17日 本周六 10:30-12:00（GTM+8），线上见～\n\n![创意脑暴.jpeg](https://img1.www.pingcap.com/prod/_a800efa48b.jpeg)\n\n## 合作伙伴\n\n![合作伙伴.png](https://img1.www.pingcap.com/prod/_c6b365d0d3.png)\n\n了解 [TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 更多精彩！\n\n","author":"PingCAP","category":3,"customUrl":"tidb-hackathon-2022-is-coming","fillInMethod":"writeDirectly","id":426,"summary":"一年一度的 TiDB Hackathon 又来啦！TiDB Hackathon 2022 主题为「Possibility at Scale」,9 月 13 日正式开启，线下决赛将在 2022 年 10 月 22 日 23 日举行。","tags":["TiDB Hackathon 2022"],"title":"TiDB Hackathon 2022丨总奖金池超 35 万！邀你唤醒代码世界的更多可能性！"}},{"relatedBlog":{"body":"![banner.jpeg](https://img1.www.pingcap.com/prod/banner_6e96e050b4.jpeg)\n\n一年一度黑客们的狂欢——[TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 报名已开启，万元奖金等你来拿，还有技术专家、顶级投资人全程坐镇，你的实力将被更多人看到。\n\nTiBD Hackathon 2022 ·「Possibility at Scale」，邀请你一起打破传统技术边界，突破固有思维局限，用 TiDB 释放创新的更多可能性。\n\n悄悄说：今年真的不卷，值得一试！\n\n两大赛道，任选：\n\n- 应用组：推荐噢，因为特别奖项更多！\n\n以体现 TiDB 产品价值为主，使用 TiDB 构建代码开源的产品、工具、应用等均可。部署方式上，更推荐基于 Cloud 构建 TiDB 相关应用。常见应用领域：游戏、电商、金融科技、公益等。\n\n- TiDB 产品组：延续传统，保持初心\n\n为 TiDB 内核产品以及 TiCDC、TiDB Lightning、TiUP 等周边工具的性能、稳定性、易用性或功能等各方面做出提升。\n\n扫描下方二维码立即报名参与！\n\n![报名.jpeg](https://img1.www.pingcap.com/prod/_3b43724e2f.jpeg)\n\n听说你想参加 TiDB Hackathon，却没有 idea？\n\n别担心，脑洞达人东旭和他的架构师朋友们在创意脑暴会上分享的项目 idea 都整理好啦，快来看看有没有你感兴趣的~（ps：搭配视频查看 idea 详细介绍，效果更佳哦~） \n\n**创意贡献嘉宾**\n\n黄东旭 PingCAP 联合创始人兼 CTO\n\n姚维 PingCAP 全球社区生态负责人\n\n张兴晔 多点系统架构师\n\nCheng Chen PingCAP Product Manager\n\n[脑暴会视频](https://www.bilibili.com/video/BV1yG411u7N9/)\n\n## 应用组\n\n![应用组.jpeg](https://img1.www.pingcap.com/prod/_e769b14808.jpeg)\n\n今年应用组的决赛参赛项目仅要求是 demo 级别的，例如以下项目示例：\n\n- OSS Insight：https://ossinsight.io/\n\n这是一个基于 TiDB 实现的，数十亿 GitHub events 数据构建的洞察工具。只要你会写 SQL，就可以基于 Docusaurus、Apache ECharts 构建一个强大、酷炫的数据洞察工具。\n\n- TiDB & Snowflake Demo：https://tidb-snowflake-e-commerce-demo.vercel.app/\n\n这是一个基于 TiDB 和 Snowflake 构建的电子商务系统，该系统使用了 TiDB 强大的实时 HTAP 能力和 Snowflake 的离线分析能力，来处理系统中大量的数据。\n\n- Ti-Click：http://ide.ti-click.com/\n\n这是 TiDB Hackathon 2021 的 20 强项目之一，项目通过在线 IDE 的方式，快速搭建基于 TiDB 的 Example App 的开发和在线编译的实验室，可帮助开发者快速学习 TiDB。\n\n- Bookshop\n\n这是一个基于 TiDB 搭建的在线书店应用，你可以通过它来学习如何导入表结构和数据，以及如何基于这些数据来编写 SQL。\n\n[这篇文章](https://docs.pingcap.com/zh/tidb/stable/dev-guide-bookshop-schema-design)也以 Bookshop 应用的数据表结构和数据为基础来编写示例 SQL，为你介绍如何导入该应用的表结构和数据，以及其数据表结构的定义。\n\n- Gitpod\n\n对于 TiDB 初学者，我们基于 Gitpod，提供了一个云原生开发环境的使用帮助，你可以直接从你的浏览器或桌面 IDE 启动一个远程的 TiDB 开发环境，快速体验 TiDB 的能力。我们编写了全新的 TiDB 开发者文档，这份文档可以帮助应用开发者，在最短时间内上手 TiDB。\n\nTiDB 开发者文档：https://docs.pingcap.com/zh/tidb/stable/dev-guide-overview\n\n## TiDB 产品组\n\n![TiDB 产品组.jpeg](https://img1.www.pingcap.com/prod/Ti_DB_77ad779a1c.jpeg)\n\n## 彩蛋组\n\n彩蛋组不可更改 TiDB/TiKV 源码，仅可使用插件方式进行 Hack。\n\n![彩蛋组.jpeg](https://img1.www.pingcap.com/prod/_f6b386df89.jpeg)\n\n希望可以给你一些方向与灵感！更多项目 idea 也可以来 [Hackathon 2022 创意库](https://asktug.com/t/topic/933124)找灵感。\n\n看到这么多 idea，你是否跃跃欲试了呢？\n\n热爱编程，勇于探索，就能参赛\n\n你离万元大奖只有一个报名的距离~\n\n了解 [TiDB Hackathon 2022 ](https://tidb.net/events/hackathon2022)更多详情！","author":"PingCAP","category":3,"customUrl":"hackathon-idea-list-for-reference","fillInMethod":"writeDirectly","id":427,"summary":"一年一度黑客们的狂欢——TiDB Hackathon 2022 报名已开启，万元奖金等你来拿，还有技术专家、顶级投资人全程坐镇，你的实力将被更多人看到。","tags":["TiDB Hackathon 2022"],"title":"Hackathon idea 清单出炉，总有一款适合你"}}]},{"id":"Blogs_425","title":"Hackathon 实用指南丨快速给 TiDB 新增一个功能","tags":["TiDB Hackathon 2022"],"category":{"name":"社区动态"},"summary":"TiDB Hackathon 2022 即将到来，你有 idea 了吗！不够了解 TiDB，不知道如何开始？本文将通过 step-by-step 的方式，介绍如何快速给 TiDB 新增加一个功能。","body":"TiDB Hackathon 2022 火热报名中！你报名了吗？你有 idea 了吗？\n\n有了 idea，但是不够了解 TiDB，不知道如何动手实践？本文将通过 step-by-step 的方式，介绍如何快速给 TiDB 新增一个功能，让没有太多知识背景的人也能快速上手。\n\nps：参加 TiDB 产品组的小伙伴，想给 TiDB 组件增加新功能的，快来围观！\n\n假设我们想要将 SST 文件导入 TiDB 中，通过新增 `LOAD SST FILE <file_path>` 语法来实现。\n\nTiDB 数据库在收到一条 SQL 请求后，大概的执行流程是 生成 AST 语法树 -> 生成执行计划 -> 构造 Executor 并执行。我们先来实现语法。\n\n## 语法实现\n\n要如何实现语法呢？我们可以照葫芦画瓢，找一个类似的 `LOAD DATA` 语法作为葫芦，然后开始画瓢。\n\n### Step-1: 新增 AST 语法树\n\n`LOAD DATA` 语法是用 `ast.LoadDataStmt` 表示的，我们照葫芦画瓢在 `tidb/parser/ast/dml.go` 中新增一个 `LoadSSTFileStmt AST` 语法树：\n\n```\n// LoadSSTFileStmt is a statement to load sst file.\ntype LoadSSTFileStmt struct {\n   dmlNode\n\n   Path string\n}\n\n// Restore implements Node interface.\nfunc (n *LoadSSTFileStmt) Restore(ctx *format.RestoreCtx) error {\n   ctx.WriteKeyWord(\"LOAD SST FILE \")\n   ctx.WriteString(n.Path)\n   return nil\n}\n\n// Accept implements Node Accept interface.\nfunc (n *LoadSSTFileStmt) Accept(v Visitor) (Node, bool) {\n   newNode, _ := v.Enter(n)\n   return v.Leave(newNode)\n}\n```\n\nRestore 方法用来根据 AST 语法树还原出对应的 SQL 语句。 Accept 方法是方便其他工具遍历这个 AST 语法树，例如 TiDB 在预处理是会通过 AST 语法树的 Accept 方法来遍历 AST 语法树中的所有节点。\n\n### Step-2：新增语法\n\nLOAD DATA 语法是通过 `LoadDataStmt` 实现的，我们也照葫芦画瓢，在 `tidb/parser/parser.y` 中，新增 `LoadSSTFileStmt` 语法，这里需要修改好几处地方，下面用 git diff 展示修改：\n\n```\ndiff --git a/parser/parser.y b/parser/parser.y\nindex 1539bb13db..079859e8a9 100644\n--- a/parser/parser.y\n+++ b/parser/parser.y\n@@ -243,6 +243,7 @@ import (\n        sqlCalcFoundRows  \"SQL_CALC_FOUND_ROWS\"\n        sqlSmallResult    \"SQL_SMALL_RESULT\"\n        ssl               \"SSL\"\n+       sst               \"SST\"\n        starting          \"STARTING\"\n        statsExtended     \"STATS_EXTENDED\"\n        straightJoin      \"STRAIGHT_JOIN\"\n@@ -908,6 +909,7 @@ import (\n        IndexAdviseStmt            \"INDEX ADVISE statement\"\n        KillStmt                   \"Kill statement\"\n        LoadDataStmt               \"Load data statement\"\n+       LoadSSTFileStmt            \"Load sst file statement\"\n        LoadStatsStmt              \"Load statistic statement\"\n        LockTablesStmt             \"Lock tables statement\"\n        NonTransactionalDeleteStmt \"Non-transactional delete statement\"\n@@ -11324,6 +11326,7 @@ Statement:\n |      IndexAdviseStmt\n |      KillStmt\n |      LoadDataStmt\n+|      LoadSSTFileStmt\n |      LoadStatsStmt\n |      PlanReplayerStmt\n |      PreparedStmt\n@@ -13496,6 +13499,14 @@ LoadDataStmt:\n                $ = x\n        }\n\n+LoadSSTFileStmt:\n+       \"LOAD\" \"SST\" \"FILE\" stringLit\n+       {\n+               $ = &ast.LoadSSTFileStmt{\n+                       Path: $4,\n+               }\n+       }\n+\n```\n\n上面的修改中：\n\n第 9 行是因为语法中 `SST` 是一个新的关键字，所以需要注册一个新的关键字。\n\n第 17 行 和 25 行是注册一个新语法叫 `LoadSSTFileStmt` 。\n\n第 33 - 40 行是定义 `LoadSSTFileStmt` 语法结构为：`LOAD SST FILE <file_path>` ，这里前 3 个关键字都是固定的，所以直接定义  `\"LOAD\" \"SST\" \"FILE\"`即可，第 4 个是文件路径，一个变量值，我们用 `stringLit` 来提取这个变量的值，然后再用这个的值来初始化 `ast.LoadSSTFileStmt`，其中 $4 是指第 4 个变量 `stringLit` 的值。\n\n因为引入了新的关键字 `SST` ，所以还需要在 `tidb/parser/misc.go` 中新增这个关键字：\n\n```\ndiff --git a/parser/misc.go b/parser/misc.go\nindex 140619bb07..418e9dd6a4 100644\n--- a/parser/misc.go\n+++ b/parser/misc.go\n@@ -669,6 +669,7 @@ var tokenMap = map[string]int{\n        \"SQL_TSI_YEAR\":             sqlTsiYear,\n        \"SQL\":                      sql,\n        \"SSL\":                      ssl,\n+       \"SST\":                      sst,\n        \"STALENESS\":                staleness,\n        \"START\":                    start,\n        \"STARTING\":                 starting,\n```\n\n### Step-3：编译和测试\n\n编译生成新的 `parser` 文件。\n\n```\ncd parser\nmake fmt  #格式化代码\nmake      # 编译生成新的 parser 文件\n```\n\n我们可以在 `tidb/parser/parser_test.go` 文件中的 `TestDMLStmt` 中新增一个测试，来验证我们新增的语法生效了，下面是 git diff 展示的修改：\n\n```\ndiff --git a/parser/parser_test.go b/parser/parser_test.go\nindex 7093c3889f..d2c75c4c59 100644\n--- a/parser/parser_test.go\n+++ b/parser/parser_test.go\n@@ -666,6 +666,9 @@ func TestDMLStmt(t *testing.T) {\n                {\"LOAD DATA LOCAL INFILE '/tmp/t.csv' IGNORE INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\\n';\", true, \"LOAD DATA LOCAL INFILE '/tmp/t.csv' IGNORE INTO TABLE `t1` FIELDS TERMINATED BY ','\"},\n                {\"LOAD DATA LOCAL INFILE '/tmp/t.csv' REPLACE INTO TABLE t1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\\n';\", true, \"LOAD DATA LOCAL INFILE '/tmp/t.csv' REPLACE INTO TABLE `t1` FIELDS TERMINATED BY ','\"},\n\n+               // load sst file test\n+               {\"load sst file 'table0.sst'\", true, \"LOAD SST FILE 'table0.sst'\"},\n+\n```\n\n然后跑测试：\n\n```\ncd parser\nmake test #跑 parser 的所有测试，快速验证可以用 go test -run=\"TestDMLStmt\" 命令只跑修改的 TestDMLStmt 测试\n```\n\n## 生成执行计划\n\nTiDB 在生成 AST 语法树后，需要生成对应的执行计划。我们需要先定义 `LOAD SST FILE` 的执行计划。同样的照葫芦画瓢，我们先在 `tidb/planner/core/common_plans.go` 文件中找到 `LOAD DATA` 的执行计划 `LoadData`, 然后开始画瓢定义 `LoadSSTFile` 执行计划：\n\n```\n// LoadSSTFile represents a load sst file plan.\ntype LoadSSTFile struct {\n        baseSchemaProducer\n\n        Path        string\n}\n```\n\n为了让 TiDB 能更具 `ast.LoadSSTFileStmt` 语法树生成对应的 `LoadSSTFile` 执行计划，\n\n需要在 `tidb/planner/core/planbuilder.go` 文件中，参考 `buildLoadData` 方法，来实现我们的 `buildLoadSSTFile` 方法，用来生成执行计划, 下面是 git diff 展示修改内容：\n\n```\ndiff --git a/planner/core/planbuilder.go b/planner/core/planbuilder.go\nindex ad7ce64748..c68e992b35 100644\n--- a/planner/core/planbuilder.go\n+++ b/planner/core/planbuilder.go\n@@ -734,6 +734,8 @@ func (b *PlanBuilder) Build(ctx context.Context, node ast.Node) (Plan, error) {\n                return b.buildInsert(ctx, x)\n        case *ast.LoadDataStmt:\n                return b.buildLoadData(ctx, x)\n+       case *ast.LoadSSTFileStmt:\n+               return b.buildLoadSSTFile(x)\n@@ -3979,6 +3981,13 @@ func (b *PlanBuilder) buildLoadData(ctx context.Context, ld *ast.LoadDataStmt) (\n        return p, nil\n }\n\n+func (b *PlanBuilder) buildLoadSSTFile(ld *ast.LoadSSTFileStmt) (Plan, error) {\n+       p := &LoadSSTFile{\n+               Path: ld.Path,\n+       }\n+       return p, nil\n+}\n+\n```\n\n## 构造 Executor 并执行\n\n生成执行计划之后，就需要构造对应的 Executor 然后执行了。TiDB 是用 Volcano 执行引擎，你可以将相关的初始化工作放在 `Open` 方法中，将主要功能的实现都放在 `Next` 方法中，以及执行完成后，在 `Close` 方法中执行相关的清理和释放资源的操作。\n\n我们需要先定义 `LOAD SST FILE` 的 Executor，并让其实现 `executor.Executor` 接口，可以把相关定义放到 `tidb/executor/executor.go` 文件中：\n\n```\n// LoadSSTFileExec represents a load sst file executor.\ntype LoadSSTFileExec struct {\n   baseExecutor\n\n   path string\n   done bool\n}\n\n// Open implements the Executor Open interface.\nfunc (e *LoadSSTFileExec) Open(ctx context.Context) error {\n   logutil.BgLogger().Warn(\"----- load sst file open, you can initialize some resource here\")\n   return nil\n}\n\n// Next implements the Executor Next interface.\nfunc (e *LoadSSTFileExec) Next(ctx context.Context, req *chunk.Chunk) error {\n   req.Reset()\n   if e.done {\n      return nil\n   }\n   e.done = true\n\n   logutil.BgLogger().Warn(\"----- load sst file exec\", zap.String(\"file\", e.path))\n   return nil\n}\n\n// Close implements the Executor Close interface.\nfunc (e *LoadSSTFileExec) Close() error {\n   logutil.BgLogger().Warn(\"----- load sst file close, you can release some resource here\")\n   return nil\n}\n```\n\n如果没有初始化工作和清理工作，你也可以不用实现 `Open` 和 `Close` 方法，因为 `baseExecutor` 已经实现过了。\n\n这里为了简化教程在 `LoadSSTFileExec Executor` 中仅仅是输出了几条 Log，你需要将自己功能具体实现的代码放在这里。\n\n然后为了让 TiDB 能够根据 `LoadSSTFile` 执行计划来生成 `LoadSSTFileExec Executor`, 需要修改 `tidb/executor/builder.go` 文件，下面是用 git diff 展示的修改：\n\n```\ndiff --git a/executor/builder.go b/executor/builder.go\nindex 1154633bd5..4f0478daa6 100644\n--- a/executor/builder.go\n+++ b/executor/builder.go\n@@ -199,6 +199,8 @@ func (b *executorBuilder) build(p plannercore.Plan) Executor {\n                return b.buildInsert(v)\n        case *plannercore.LoadData:\n                return b.buildLoadData(v)\n+       case *plannercore.LoadSSTFile:\n+               return b.buildLoadSSTFile(v)\n        case *plannercore.LoadStats:\n                return b.buildLoadStats(v)\n        case *plannercore.IndexAdvise:\n@@ -944,6 +946,14 @@ func (b *executorBuilder) buildLoadData(v *plannercore.LoadData) Executor {\n        return loadDataExec\n }\n\n+func (b *executorBuilder) buildLoadSSTFile(v *plannercore.LoadSSTFile) Executor {\n+       e := &LoadSSTFileExec{\n+               baseExecutor: newBaseExecutor(b.ctx, nil, v.ID()),\n+               path:         v.Path,\n+       }\n+       return e\n+}\n+\n```\n\n## 验证\n\n到此，我们已经成功的在 TiDB 中新增了一个 “功能”， 我们可以编译 TiDB 并启动后验证下：\n\n```\nmake    #编译 TiDB server\nbin/tidb-server  # 启动一个 TiDB server\n```\n\n然后新起一个终端，用 mysql 客户端连上去试试新功能：\n\n```\n▶ mysql -u root -h 127.0.0.1 -P 4000\n\nmysql> load sst file 'table0.sst';\nQuery OK, 0 rows affected (0.00 sec)\n```\n\n可以看到执行成功了，并且在 tidb-server 的输出日志中，可以看到我们这个功能的 Executor 执行时的日志输出：\n\n```\n[2022/09/19 15:24:02.745 +08:00] [WARN] [executor.go:2213] [\"----- load sst file open, you can initialize some resource here\"]\n[2022/09/19 15:24:02.745 +08:00] [WARN] [executor.go:2225] [\"----- load sst file exec\"] [file=table0.sst]\n[2022/09/19 15:24:02.745 +08:00] [WARN] [executor.go:2231] [\"----- load sst file close, you can release some resource here\"]\n```\n\n## 总结\n\n本文的代码示例：https://github.com/pingcap/tidb/pull/37936/files\n\n本文通过“照葫芦画瓢” 的方式，教你如何在 TiDB 中新增一个功能，但也忽略了一些细节，例如权限检查，添加完备的测试等等，希望能对读者有所帮助。如果想要了解更多的知识背景和细节，推荐阅读 [TiDB Development Guide](https://pingcap.github.io/tidb-dev-guide/) 和 [TiDB 源码阅读](/blog/?tag=TiDB%20源码阅读)博客。","date":"2022-10-09","author":"陈霜","fillInMethod":"writeDirectly","customUrl":"hackathon-guide-adds-a-new-feature-to-tidb","file":null,"relatedBlogs":[{"relatedBlog":{"body":"![hackathon 2022 kv.jpeg](https://img1.www.pingcap.com/prod/hackathon_2022_kv_000f450a54.jpeg)\n\n一年一度的 TiDB Hackathon 又来啦！\n\n[TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 主题为「**Possibility at Scale**」，9 月 13 日正式开启，线下决赛将在 2022 年 10 月 22 - 23 日举行。期待与你一起打破传统技术边界，突破固有思维局限，用 TiDB 释放创新的更多可能性。\n\n本届 TiDB Hackathon 将面向更广泛人群，分为**应用组**与 **TiDB 产品组**两大赛道。无论你是应用开发者、数据库开发者、数据库上下游生态从业人员，还是数据库使用者，都可以找到适合自己的方向，一起“玩转” TiDB。\n\nTiDB Hackathon 报名通道于 2022 年 9 月 13 日正式开启，**选手们可以自行组队参赛，通过初赛甄选后，将在现场完成 Coding 及决赛答辩，优胜队伍将获得奖金、技术和资源商的支持**。大赛评委阵容豪华，数据库领域资深专家、社区技术大牛、顶级投资人代表将对项目进行深度点评。此外，还有顶级投资人全程参与评选，让你的实力被更多人看到。\n\n**扫描下图二维码，立即报名参赛**，或前往 [TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 活动页报名。\n\n![报名参赛.jpeg](https://img1.www.pingcap.com/prod/_f7bfacf978.jpeg)\n\n从 2017 年到 2022 年，TiDB Hackathon 不断升级，吸引了全球 1000 + 技术爱好者参与，先后诞生了诸如 UDF 引擎、TiExec、TiMatch 等深受好评的硬核项目，也有 zh.md、TiDB 驾驶舱、pCloud 等新颖有趣的项目。同时，部分优秀项目还在海内外媒体平台获得了多重曝光，借助 TiDB 社区力量为项目提供更多生命力。\n\n在 TiDB Hackathon ，你可以尽情发挥想象力与创造力，全情投入，实现自己的 idea。我们希望你可以永葆对技术的热情与好奇心，在代码的世界中勇敢探索、一往无前。我们在 TiDB Hackathon 2022 等你，期待与你共赴这场技术盛宴！\n\n## 赛事亮点\n\n🌟 **奖金丰厚**\n\n大赛总奖金池高达 35 万元，奖项多达 10+ 个，涵盖各个方向，力求全方位挖掘各参赛项目的价值。\n\n🌟 **各路大神同台竞技**\n\n技术大神齐聚一堂，上演“神仙打架”，场面超燃。高手之间的巅峰对决，精彩纷呈，让人大开眼界。\n\n🌟 **高质量交流**\n\n数据领域知名专家、社区技术大牛担任大赛评委，对项目进行深入点评，还有顶级投资人全程参与评选，你将不止收获硬核的技术反馈，还会获得前瞻性启发。\n\n🌟 **优秀项目专题采访**\n\n大赛结束后，我们将对优秀项目进行专题采访，在海内外技术圈多重曝光，提升优秀项目的知名度，借助 TiDB 社区力量为项目提供更多生命力。\n\n## 丰厚奖金\n\n**奖金池 35 万元，10+ 奖项，20+ 获奖团队**\n\n![丰厚奖金.jpeg](https://img1.www.pingcap.com/prod/_d265519d19.jpeg)\n\n**神秘定制社区周边**\n\n![定制社区周边.jpeg](https://img1.www.pingcap.com/prod/_c6c05c4a61.jpeg)\n\n## 参赛对象\n\n不管你是数据库内核工程师、数据库生态上下游开发者，还是应用开发者，只要你有 idea，都可以报名参赛，一展你的风采！\n\n## 赛道设置\n\n**应用组**\n\n以体现 TiDB 产品价值为主，基于 TiDB 之上实现代码开源的产品、工具、应用等均可。部署方式上，更推荐基于 Cloud 构建 TiDB 相关应用。推荐领域：游戏、电商、金融科技、公益等。\n\n**TiDB 产品组**\n\n为 TiDB 内核产品以及 TiCDC、TiDB Lightning、TiUP 等周边工具的性能、稳定性、易用性或功能等各方面做出提升。\n\n## 赛程安排\n\n- 报名：即日起 - 10 月 17 日，开启报名\n\n- 组队：9 月 17 日，参加「非正式会谈 — 创意脑暴会」，获取项目灵感（详见下方介绍）\n\n- 线上初赛：报名后 -  10 月 17 日，提交 RFC 进入初赛环节\n\n- 名单公布：10 月 19 日，查看决赛入围名单\n\n- 现场 Coding & 决赛：10 月 22 日 - 10 月 23 日，现场 Coding & 决赛答辩\n\n![比赛日程.png](https://img1.www.pingcap.com/prod/_357da0cc3c.png)\n\n## 评委阵容\n\n数据库领域知名专家、社区技术大牛、顶级投资人代表等担当评委，还有顶级投资人全程坐镇，对比赛项目深入点评。\n\n![评委.png](https://img1.www.pingcap.com/prod/_db0a886a7b.png)\n\n<center>（评委按姓名首字母排序）</center>\n\n比赛有输赢，技术无高低。即便最终未能问鼎巅峰，朝着心之所向全力冲刺依旧是一段值得回忆的旅程。秉承不断突破和创造的黑客精神，来一场技术的狂欢盛宴吧。放码过来！\n\n## 创意脑暴会给你灵感\n\n**TiDB Hackathon 2022 非正式会谈 —— 创意脑暴会**来啦，这里有超多 idea，特邀东旭以及资深架构师们在线脑暴，给你超丰富项目灵感。9月17日 本周六 10:30-12:00（GTM+8），线上见～\n\n![创意脑暴.jpeg](https://img1.www.pingcap.com/prod/_a800efa48b.jpeg)\n\n## 合作伙伴\n\n![合作伙伴.png](https://img1.www.pingcap.com/prod/_c6b365d0d3.png)\n\n了解 [TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 更多精彩！\n\n","author":"PingCAP","category":3,"customUrl":"tidb-hackathon-2022-is-coming","fillInMethod":"writeDirectly","id":426,"summary":"一年一度的 TiDB Hackathon 又来啦！TiDB Hackathon 2022 主题为「Possibility at Scale」,9 月 13 日正式开启，线下决赛将在 2022 年 10 月 22 日 23 日举行。","tags":["TiDB Hackathon 2022"],"title":"TiDB Hackathon 2022丨总奖金池超 35 万！邀你唤醒代码世界的更多可能性！"}},{"relatedBlog":{"body":"![banner.jpeg](https://img1.www.pingcap.com/prod/banner_6e96e050b4.jpeg)\n\n一年一度黑客们的狂欢——[TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 报名已开启，万元奖金等你来拿，还有技术专家、顶级投资人全程坐镇，你的实力将被更多人看到。\n\nTiBD Hackathon 2022 ·「Possibility at Scale」，邀请你一起打破传统技术边界，突破固有思维局限，用 TiDB 释放创新的更多可能性。\n\n悄悄说：今年真的不卷，值得一试！\n\n两大赛道，任选：\n\n- 应用组：推荐噢，因为特别奖项更多！\n\n以体现 TiDB 产品价值为主，使用 TiDB 构建代码开源的产品、工具、应用等均可。部署方式上，更推荐基于 Cloud 构建 TiDB 相关应用。常见应用领域：游戏、电商、金融科技、公益等。\n\n- TiDB 产品组：延续传统，保持初心\n\n为 TiDB 内核产品以及 TiCDC、TiDB Lightning、TiUP 等周边工具的性能、稳定性、易用性或功能等各方面做出提升。\n\n扫描下方二维码立即报名参与！\n\n![报名.jpeg](https://img1.www.pingcap.com/prod/_3b43724e2f.jpeg)\n\n听说你想参加 TiDB Hackathon，却没有 idea？\n\n别担心，脑洞达人东旭和他的架构师朋友们在创意脑暴会上分享的项目 idea 都整理好啦，快来看看有没有你感兴趣的~（ps：搭配视频查看 idea 详细介绍，效果更佳哦~） \n\n**创意贡献嘉宾**\n\n黄东旭 PingCAP 联合创始人兼 CTO\n\n姚维 PingCAP 全球社区生态负责人\n\n张兴晔 多点系统架构师\n\nCheng Chen PingCAP Product Manager\n\n[脑暴会视频](https://www.bilibili.com/video/BV1yG411u7N9/)\n\n## 应用组\n\n![应用组.jpeg](https://img1.www.pingcap.com/prod/_e769b14808.jpeg)\n\n今年应用组的决赛参赛项目仅要求是 demo 级别的，例如以下项目示例：\n\n- OSS Insight：https://ossinsight.io/\n\n这是一个基于 TiDB 实现的，数十亿 GitHub events 数据构建的洞察工具。只要你会写 SQL，就可以基于 Docusaurus、Apache ECharts 构建一个强大、酷炫的数据洞察工具。\n\n- TiDB & Snowflake Demo：https://tidb-snowflake-e-commerce-demo.vercel.app/\n\n这是一个基于 TiDB 和 Snowflake 构建的电子商务系统，该系统使用了 TiDB 强大的实时 HTAP 能力和 Snowflake 的离线分析能力，来处理系统中大量的数据。\n\n- Ti-Click：http://ide.ti-click.com/\n\n这是 TiDB Hackathon 2021 的 20 强项目之一，项目通过在线 IDE 的方式，快速搭建基于 TiDB 的 Example App 的开发和在线编译的实验室，可帮助开发者快速学习 TiDB。\n\n- Bookshop\n\n这是一个基于 TiDB 搭建的在线书店应用，你可以通过它来学习如何导入表结构和数据，以及如何基于这些数据来编写 SQL。\n\n[这篇文章](https://docs.pingcap.com/zh/tidb/stable/dev-guide-bookshop-schema-design)也以 Bookshop 应用的数据表结构和数据为基础来编写示例 SQL，为你介绍如何导入该应用的表结构和数据，以及其数据表结构的定义。\n\n- Gitpod\n\n对于 TiDB 初学者，我们基于 Gitpod，提供了一个云原生开发环境的使用帮助，你可以直接从你的浏览器或桌面 IDE 启动一个远程的 TiDB 开发环境，快速体验 TiDB 的能力。我们编写了全新的 TiDB 开发者文档，这份文档可以帮助应用开发者，在最短时间内上手 TiDB。\n\nTiDB 开发者文档：https://docs.pingcap.com/zh/tidb/stable/dev-guide-overview\n\n## TiDB 产品组\n\n![TiDB 产品组.jpeg](https://img1.www.pingcap.com/prod/Ti_DB_77ad779a1c.jpeg)\n\n## 彩蛋组\n\n彩蛋组不可更改 TiDB/TiKV 源码，仅可使用插件方式进行 Hack。\n\n![彩蛋组.jpeg](https://img1.www.pingcap.com/prod/_f6b386df89.jpeg)\n\n希望可以给你一些方向与灵感！更多项目 idea 也可以来 [Hackathon 2022 创意库](https://asktug.com/t/topic/933124)找灵感。\n\n看到这么多 idea，你是否跃跃欲试了呢？\n\n热爱编程，勇于探索，就能参赛\n\n你离万元大奖只有一个报名的距离~\n\n了解 [TiDB Hackathon 2022 ](https://tidb.net/events/hackathon2022)更多详情！","author":"PingCAP","category":3,"customUrl":"hackathon-idea-list-for-reference","fillInMethod":"writeDirectly","id":427,"summary":"一年一度黑客们的狂欢——TiDB Hackathon 2022 报名已开启，万元奖金等你来拿，还有技术专家、顶级投资人全程坐镇，你的实力将被更多人看到。","tags":["TiDB Hackathon 2022"],"title":"Hackathon idea 清单出炉，总有一款适合你"}}]},{"id":"Blogs_427","title":"Hackathon idea 清单出炉，总有一款适合你","tags":["TiDB Hackathon 2022"],"category":{"name":"社区动态"},"summary":"一年一度黑客们的狂欢——TiDB Hackathon 2022 报名已开启，万元奖金等你来拿，还有技术专家、顶级投资人全程坐镇，你的实力将被更多人看到。","body":"![banner.jpeg](https://img1.www.pingcap.com/prod/banner_6e96e050b4.jpeg)\n\n一年一度黑客们的狂欢——[TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 报名已开启，万元奖金等你来拿，还有技术专家、顶级投资人全程坐镇，你的实力将被更多人看到。\n\nTiBD Hackathon 2022 ·「Possibility at Scale」，邀请你一起打破传统技术边界，突破固有思维局限，用 TiDB 释放创新的更多可能性。\n\n悄悄说：今年真的不卷，值得一试！\n\n两大赛道，任选：\n\n- 应用组：推荐噢，因为特别奖项更多！\n\n以体现 TiDB 产品价值为主，使用 TiDB 构建代码开源的产品、工具、应用等均可。部署方式上，更推荐基于 Cloud 构建 TiDB 相关应用。常见应用领域：游戏、电商、金融科技、公益等。\n\n- TiDB 产品组：延续传统，保持初心\n\n为 TiDB 内核产品以及 TiCDC、TiDB Lightning、TiUP 等周边工具的性能、稳定性、易用性或功能等各方面做出提升。\n\n扫描下方二维码立即报名参与！\n\n![报名.jpeg](https://img1.www.pingcap.com/prod/_3b43724e2f.jpeg)\n\n听说你想参加 TiDB Hackathon，却没有 idea？\n\n别担心，脑洞达人东旭和他的架构师朋友们在创意脑暴会上分享的项目 idea 都整理好啦，快来看看有没有你感兴趣的~（ps：搭配视频查看 idea 详细介绍，效果更佳哦~） \n\n**创意贡献嘉宾**\n\n黄东旭 PingCAP 联合创始人兼 CTO\n\n姚维 PingCAP 全球社区生态负责人\n\n张兴晔 多点系统架构师\n\nCheng Chen PingCAP Product Manager\n\n[脑暴会视频](https://www.bilibili.com/video/BV1yG411u7N9/)\n\n## 应用组\n\n![应用组.jpeg](https://img1.www.pingcap.com/prod/_e769b14808.jpeg)\n\n今年应用组的决赛参赛项目仅要求是 demo 级别的，例如以下项目示例：\n\n- OSS Insight：https://ossinsight.io/\n\n这是一个基于 TiDB 实现的，数十亿 GitHub events 数据构建的洞察工具。只要你会写 SQL，就可以基于 Docusaurus、Apache ECharts 构建一个强大、酷炫的数据洞察工具。\n\n- TiDB & Snowflake Demo：https://tidb-snowflake-e-commerce-demo.vercel.app/\n\n这是一个基于 TiDB 和 Snowflake 构建的电子商务系统，该系统使用了 TiDB 强大的实时 HTAP 能力和 Snowflake 的离线分析能力，来处理系统中大量的数据。\n\n- Ti-Click：http://ide.ti-click.com/\n\n这是 TiDB Hackathon 2021 的 20 强项目之一，项目通过在线 IDE 的方式，快速搭建基于 TiDB 的 Example App 的开发和在线编译的实验室，可帮助开发者快速学习 TiDB。\n\n- Bookshop\n\n这是一个基于 TiDB 搭建的在线书店应用，你可以通过它来学习如何导入表结构和数据，以及如何基于这些数据来编写 SQL。\n\n[这篇文章](https://docs.pingcap.com/zh/tidb/stable/dev-guide-bookshop-schema-design)也以 Bookshop 应用的数据表结构和数据为基础来编写示例 SQL，为你介绍如何导入该应用的表结构和数据，以及其数据表结构的定义。\n\n- Gitpod\n\n对于 TiDB 初学者，我们基于 Gitpod，提供了一个云原生开发环境的使用帮助，你可以直接从你的浏览器或桌面 IDE 启动一个远程的 TiDB 开发环境，快速体验 TiDB 的能力。我们编写了全新的 TiDB 开发者文档，这份文档可以帮助应用开发者，在最短时间内上手 TiDB。\n\nTiDB 开发者文档：https://docs.pingcap.com/zh/tidb/stable/dev-guide-overview\n\n## TiDB 产品组\n\n![TiDB 产品组.jpeg](https://img1.www.pingcap.com/prod/Ti_DB_77ad779a1c.jpeg)\n\n## 彩蛋组\n\n彩蛋组不可更改 TiDB/TiKV 源码，仅可使用插件方式进行 Hack。\n\n![彩蛋组.jpeg](https://img1.www.pingcap.com/prod/_f6b386df89.jpeg)\n\n希望可以给你一些方向与灵感！更多项目 idea 也可以来 [Hackathon 2022 创意库](https://asktug.com/t/topic/933124)找灵感。\n\n看到这么多 idea，你是否跃跃欲试了呢？\n\n热爱编程，勇于探索，就能参赛\n\n你离万元大奖只有一个报名的距离~\n\n了解 [TiDB Hackathon 2022 ](https://tidb.net/events/hackathon2022)更多详情！","date":"2022-09-26","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"hackathon-idea-list-for-reference","file":null,"relatedBlogs":[{"relatedBlog":{"body":"![hackathon 2022 kv.jpeg](https://img1.www.pingcap.com/prod/hackathon_2022_kv_000f450a54.jpeg)\n\n一年一度的 TiDB Hackathon 又来啦！\n\n[TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 主题为「**Possibility at Scale**」，9 月 13 日正式开启，线下决赛将在 2022 年 10 月 22 - 23 日举行。期待与你一起打破传统技术边界，突破固有思维局限，用 TiDB 释放创新的更多可能性。\n\n本届 TiDB Hackathon 将面向更广泛人群，分为**应用组**与 **TiDB 产品组**两大赛道。无论你是应用开发者、数据库开发者、数据库上下游生态从业人员，还是数据库使用者，都可以找到适合自己的方向，一起“玩转” TiDB。\n\nTiDB Hackathon 报名通道于 2022 年 9 月 13 日正式开启，**选手们可以自行组队参赛，通过初赛甄选后，将在现场完成 Coding 及决赛答辩，优胜队伍将获得奖金、技术和资源商的支持**。大赛评委阵容豪华，数据库领域资深专家、社区技术大牛、顶级投资人代表将对项目进行深度点评。此外，还有顶级投资人全程参与评选，让你的实力被更多人看到。\n\n**扫描下图二维码，立即报名参赛**，或前往 [TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 活动页报名。\n\n![报名参赛.jpeg](https://img1.www.pingcap.com/prod/_f7bfacf978.jpeg)\n\n从 2017 年到 2022 年，TiDB Hackathon 不断升级，吸引了全球 1000 + 技术爱好者参与，先后诞生了诸如 UDF 引擎、TiExec、TiMatch 等深受好评的硬核项目，也有 zh.md、TiDB 驾驶舱、pCloud 等新颖有趣的项目。同时，部分优秀项目还在海内外媒体平台获得了多重曝光，借助 TiDB 社区力量为项目提供更多生命力。\n\n在 TiDB Hackathon ，你可以尽情发挥想象力与创造力，全情投入，实现自己的 idea。我们希望你可以永葆对技术的热情与好奇心，在代码的世界中勇敢探索、一往无前。我们在 TiDB Hackathon 2022 等你，期待与你共赴这场技术盛宴！\n\n## 赛事亮点\n\n🌟 **奖金丰厚**\n\n大赛总奖金池高达 35 万元，奖项多达 10+ 个，涵盖各个方向，力求全方位挖掘各参赛项目的价值。\n\n🌟 **各路大神同台竞技**\n\n技术大神齐聚一堂，上演“神仙打架”，场面超燃。高手之间的巅峰对决，精彩纷呈，让人大开眼界。\n\n🌟 **高质量交流**\n\n数据领域知名专家、社区技术大牛担任大赛评委，对项目进行深入点评，还有顶级投资人全程参与评选，你将不止收获硬核的技术反馈，还会获得前瞻性启发。\n\n🌟 **优秀项目专题采访**\n\n大赛结束后，我们将对优秀项目进行专题采访，在海内外技术圈多重曝光，提升优秀项目的知名度，借助 TiDB 社区力量为项目提供更多生命力。\n\n## 丰厚奖金\n\n**奖金池 35 万元，10+ 奖项，20+ 获奖团队**\n\n![丰厚奖金.jpeg](https://img1.www.pingcap.com/prod/_d265519d19.jpeg)\n\n**神秘定制社区周边**\n\n![定制社区周边.jpeg](https://img1.www.pingcap.com/prod/_c6c05c4a61.jpeg)\n\n## 参赛对象\n\n不管你是数据库内核工程师、数据库生态上下游开发者，还是应用开发者，只要你有 idea，都可以报名参赛，一展你的风采！\n\n## 赛道设置\n\n**应用组**\n\n以体现 TiDB 产品价值为主，基于 TiDB 之上实现代码开源的产品、工具、应用等均可。部署方式上，更推荐基于 Cloud 构建 TiDB 相关应用。推荐领域：游戏、电商、金融科技、公益等。\n\n**TiDB 产品组**\n\n为 TiDB 内核产品以及 TiCDC、TiDB Lightning、TiUP 等周边工具的性能、稳定性、易用性或功能等各方面做出提升。\n\n## 赛程安排\n\n- 报名：即日起 - 10 月 17 日，开启报名\n\n- 组队：9 月 17 日，参加「非正式会谈 — 创意脑暴会」，获取项目灵感（详见下方介绍）\n\n- 线上初赛：报名后 -  10 月 17 日，提交 RFC 进入初赛环节\n\n- 名单公布：10 月 19 日，查看决赛入围名单\n\n- 现场 Coding & 决赛：10 月 22 日 - 10 月 23 日，现场 Coding & 决赛答辩\n\n![比赛日程.png](https://img1.www.pingcap.com/prod/_357da0cc3c.png)\n\n## 评委阵容\n\n数据库领域知名专家、社区技术大牛、顶级投资人代表等担当评委，还有顶级投资人全程坐镇，对比赛项目深入点评。\n\n![评委.png](https://img1.www.pingcap.com/prod/_db0a886a7b.png)\n\n<center>（评委按姓名首字母排序）</center>\n\n比赛有输赢，技术无高低。即便最终未能问鼎巅峰，朝着心之所向全力冲刺依旧是一段值得回忆的旅程。秉承不断突破和创造的黑客精神，来一场技术的狂欢盛宴吧。放码过来！\n\n## 创意脑暴会给你灵感\n\n**TiDB Hackathon 2022 非正式会谈 —— 创意脑暴会**来啦，这里有超多 idea，特邀东旭以及资深架构师们在线脑暴，给你超丰富项目灵感。9月17日 本周六 10:30-12:00（GTM+8），线上见～\n\n![创意脑暴.jpeg](https://img1.www.pingcap.com/prod/_a800efa48b.jpeg)\n\n## 合作伙伴\n\n![合作伙伴.png](https://img1.www.pingcap.com/prod/_c6b365d0d3.png)\n\n了解 [TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 更多精彩！\n\n","author":"PingCAP","category":3,"customUrl":"tidb-hackathon-2022-is-coming","fillInMethod":"writeDirectly","id":426,"summary":"一年一度的 TiDB Hackathon 又来啦！TiDB Hackathon 2022 主题为「Possibility at Scale」,9 月 13 日正式开启，线下决赛将在 2022 年 10 月 22 日 23 日举行。","tags":["TiDB Hackathon 2022"],"title":"TiDB Hackathon 2022丨总奖金池超 35 万！邀你唤醒代码世界的更多可能性！"}}]},{"id":"Blogs_426","title":"TiDB Hackathon 2022丨总奖金池超 35 万！邀你唤醒代码世界的更多可能性！","tags":["TiDB Hackathon 2022"],"category":{"name":"社区动态"},"summary":"一年一度的 TiDB Hackathon 又来啦！TiDB Hackathon 2022 主题为「Possibility at Scale」,9 月 13 日正式开启，线下决赛将在 2022 年 10 月 22 日 23 日举行。","body":"![hackathon 2022 kv.jpeg](https://img1.www.pingcap.com/prod/hackathon_2022_kv_000f450a54.jpeg)\n\n一年一度的 TiDB Hackathon 又来啦！\n\n[TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 主题为「**Possibility at Scale**」，9 月 13 日正式开启，线下决赛将在 2022 年 10 月 22 - 23 日举行。期待与你一起打破传统技术边界，突破固有思维局限，用 TiDB 释放创新的更多可能性。\n\n本届 TiDB Hackathon 将面向更广泛人群，分为**应用组**与 **TiDB 产品组**两大赛道。无论你是应用开发者、数据库开发者、数据库上下游生态从业人员，还是数据库使用者，都可以找到适合自己的方向，一起“玩转” TiDB。\n\nTiDB Hackathon 报名通道于 2022 年 9 月 13 日正式开启，**选手们可以自行组队参赛，通过初赛甄选后，将在现场完成 Coding 及决赛答辩，优胜队伍将获得奖金、技术和资源商的支持**。大赛评委阵容豪华，数据库领域资深专家、社区技术大牛、顶级投资人代表将对项目进行深度点评。此外，还有顶级投资人全程参与评选，让你的实力被更多人看到。\n\n**扫描下图二维码，立即报名参赛**，或前往 [TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 活动页报名。\n\n![报名参赛.jpeg](https://img1.www.pingcap.com/prod/_f7bfacf978.jpeg)\n\n从 2017 年到 2022 年，TiDB Hackathon 不断升级，吸引了全球 1000 + 技术爱好者参与，先后诞生了诸如 UDF 引擎、TiExec、TiMatch 等深受好评的硬核项目，也有 zh.md、TiDB 驾驶舱、pCloud 等新颖有趣的项目。同时，部分优秀项目还在海内外媒体平台获得了多重曝光，借助 TiDB 社区力量为项目提供更多生命力。\n\n在 TiDB Hackathon ，你可以尽情发挥想象力与创造力，全情投入，实现自己的 idea。我们希望你可以永葆对技术的热情与好奇心，在代码的世界中勇敢探索、一往无前。我们在 TiDB Hackathon 2022 等你，期待与你共赴这场技术盛宴！\n\n## 赛事亮点\n\n🌟 **奖金丰厚**\n\n大赛总奖金池高达 35 万元，奖项多达 10+ 个，涵盖各个方向，力求全方位挖掘各参赛项目的价值。\n\n🌟 **各路大神同台竞技**\n\n技术大神齐聚一堂，上演“神仙打架”，场面超燃。高手之间的巅峰对决，精彩纷呈，让人大开眼界。\n\n🌟 **高质量交流**\n\n数据领域知名专家、社区技术大牛担任大赛评委，对项目进行深入点评，还有顶级投资人全程参与评选，你将不止收获硬核的技术反馈，还会获得前瞻性启发。\n\n🌟 **优秀项目专题采访**\n\n大赛结束后，我们将对优秀项目进行专题采访，在海内外技术圈多重曝光，提升优秀项目的知名度，借助 TiDB 社区力量为项目提供更多生命力。\n\n## 丰厚奖金\n\n**奖金池 35 万元，10+ 奖项，20+ 获奖团队**\n\n![丰厚奖金.jpeg](https://img1.www.pingcap.com/prod/_d265519d19.jpeg)\n\n**神秘定制社区周边**\n\n![定制社区周边.jpeg](https://img1.www.pingcap.com/prod/_c6c05c4a61.jpeg)\n\n## 参赛对象\n\n不管你是数据库内核工程师、数据库生态上下游开发者，还是应用开发者，只要你有 idea，都可以报名参赛，一展你的风采！\n\n## 赛道设置\n\n**应用组**\n\n以体现 TiDB 产品价值为主，基于 TiDB 之上实现代码开源的产品、工具、应用等均可。部署方式上，更推荐基于 Cloud 构建 TiDB 相关应用。推荐领域：游戏、电商、金融科技、公益等。\n\n**TiDB 产品组**\n\n为 TiDB 内核产品以及 TiCDC、TiDB Lightning、TiUP 等周边工具的性能、稳定性、易用性或功能等各方面做出提升。\n\n## 赛程安排\n\n- 报名：即日起 - 10 月 17 日，开启报名\n\n- 组队：9 月 17 日，参加「非正式会谈 — 创意脑暴会」，获取项目灵感（详见下方介绍）\n\n- 线上初赛：报名后 -  10 月 17 日，提交 RFC 进入初赛环节\n\n- 名单公布：10 月 19 日，查看决赛入围名单\n\n- 现场 Coding & 决赛：10 月 22 日 - 10 月 23 日，现场 Coding & 决赛答辩\n\n![比赛日程.png](https://img1.www.pingcap.com/prod/_357da0cc3c.png)\n\n## 评委阵容\n\n数据库领域知名专家、社区技术大牛、顶级投资人代表等担当评委，还有顶级投资人全程坐镇，对比赛项目深入点评。\n\n![评委.png](https://img1.www.pingcap.com/prod/_db0a886a7b.png)\n\n<center>（评委按姓名首字母排序）</center>\n\n比赛有输赢，技术无高低。即便最终未能问鼎巅峰，朝着心之所向全力冲刺依旧是一段值得回忆的旅程。秉承不断突破和创造的黑客精神，来一场技术的狂欢盛宴吧。放码过来！\n\n## 创意脑暴会给你灵感\n\n**TiDB Hackathon 2022 非正式会谈 —— 创意脑暴会**来啦，这里有超多 idea，特邀东旭以及资深架构师们在线脑暴，给你超丰富项目灵感。9月17日 本周六 10:30-12:00（GTM+8），线上见～\n\n![创意脑暴.jpeg](https://img1.www.pingcap.com/prod/_a800efa48b.jpeg)\n\n## 合作伙伴\n\n![合作伙伴.png](https://img1.www.pingcap.com/prod/_c6b365d0d3.png)\n\n了解 [TiDB Hackathon 2022](https://tidb.net/events/hackathon2022) 更多精彩！\n\n","date":"2022-09-14","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"tidb-hackathon-2022-is-coming","file":null,"relatedBlogs":[]},{"id":"Blogs_410","title":"《TiDB 6.x in Action》发布，凝聚社区集体智慧的 6.x 实践汇总！","tags":["TiDB"],"category":{"name":"社区动态"},"summary":"为了帮助更多的用户把 TiDB 6.x 新版本中那些“好用”的特性用起来，我们集结社区的集体智慧，共同创作了《TiDB 6.x in Action》。今天，这本书正式发布啦！","body":"今年，TiDB 已经发布了 6.0 和 6.1 两个较大的版本更新，在 6.0 中大幅度加强了 TiDB 的可管理性和可运维性， 6.1 中又进一步提升了 TiDB 产品的稳定性。为了帮助更多的用户把新版本中这些“好用”的特性用起来，我们集结社区的集体智慧，共同创作了[《TiDB 6.x in Action》](https://tidb.net/book/book-rush/)。今天，这本书正式发布啦！\n\n![TiDB 6.x in action.jpeg](https://img1.www.pingcap.com/prod/Ti_DB_6_x_in_action_b29a77c52d.jpeg)\n\n## TiDB 6.x in Action 内容概览\n\n《TiDB 6.x in Action》分为 TiDB 6.x 原理和特性、TiDB Developer 体验指南、TiDB 6.x 可管理性、TiDB 6.x 内核优化与性能提升、TiDB 6.x 测评、TiDB 6.x 最佳实践 6 大内容模块，汇聚了 TiDB 6.x 新特性的原理、测评、试用心得等等干货。不管你是 DBA 运维还是应用开发者，如果你正在或有意向使用 TiDB 6.x，这本书都可以给你提供参考和实践指南。\n\n![TiDB 6.x in Action-目录.png](https://img1.www.pingcap.com/prod/Ti_DB_6_x_in_Action_62bc5b15d9.png)\n\n针对 TiDB 6.x 中引入的十几个新特性，比如热点小表缓存，更多算子和函数支持，数据放置框架（Placement Rules In SQL），TiUniManager ，PingCAP Clinic 等，《TiDB 6.x in Action》中都有单独的章节策划，每个章节都有用户实践文章的收录；针对 4 月份刚刚开源的 TiFlash，电子书专门策划了“TiFlash 源码阅读”章节，帮助大家了解 TiFlash 背后的设计原理；另外值得关注的是，本书还专门针对应用开发者人群，策划了“TiDB Developer 体验指南”的章节，帮助用户了解如何基于 TiDB 构建不同语言的应用程序。\n\n### 大咖推荐\n\n**刘奇**，PingCAP 创始人兼 CEO\n\nTiDB 6.0 提供了很多我非常喜欢的易用性改进，也提供了一些我们称作元功能的功能 (Placement Rules)，这个功能的意义就像分布式系统里面的元数据，本身只是整个系统数据很小的一部分，但带来了整个系统巨大的存储潜力，我也希望看到这些元功能撑起更多的各种场景下的使用创新，在社区的集体智慧中不断突破想象力边界，给大家带来更多惊喜。\n\n**贾世闻**，京东科技架构师，old TiDBer\n\n很高兴看到 TiDB Book Rush 6.0 的成果。本次 Book Rush 因为档期问题没能参与，有些遗憾。2020 年第一次 Book Rush 以 4.0 为蓝本，后来有了《TiDB 4.0 in Action》。用一个词来形容看到新版本的第一感受就是 evolution 。新特性带来新的用户体验，希望 TiDB 不断进化，带来更多惊喜。\n\n**孙晓光**，PingCAP Cloud Ecosystem 团队负责人\n\n两年间 TiDB 有了长足的进步，《TiDB 6.x in Action》也为大家带来全面更新的 TiDB 知识。感谢社区伙伴们的贡献，相信 TiDB in Action 会为大家更好地使用和理解 TiDB 带来巨大的帮助。\n\n**杨攀**，TDengine 开发者关系和生态 VP\n\n24 小时分布式成书的《TiDB 4.0 in Action》在当年给大家留下了深刻的印象。开放协作是这个世界上最酷的生产力，《TiDB 6.x in Action》将再次向我们展现开源和开源社区的力量。也希望 PingCAP 代表的头部开源厂商不断去探索开源协作的新形式、新边界，推动开源社区不断发展壮大。\n\n### 凝聚社区集体智慧的 6.x 实践汇总\n\n《TiDB 6.x in Action》托管在 GitHub 上，活动之初就公布了电子书大纲，整个创作过程耗时 3 个月，历经新版本试用、文章撰写、文章 Review、文章修改、提交 PR 等环节，每个环节都凝聚了参与者非常多的精力和付出，给所有参与者们点赞！\n\n![社区昵称词云.png](https://img1.www.pingcap.com/prod/_3ec0ea57ea.png)\n<center>上图为所有报名小伙伴的社区昵称词云</center> \n\n电子书最终共收录 46 篇文章，这些来自社区小伙伴的文章，都是用户在自己的环境里使用 TiDB 6.x 的实践总结，每一篇文章都图文并茂，有实际操作的依据，并且在试用过程中遇到的问题及解决方案也都被总结到了文章中。\n\n此外，由社区活跃成员和 PingCAP 产研小伙伴们组成的 Reviewer 小组，历时 2 个多月，对每篇文章都进行了至少 2 遍的深度审核，在文章正确性和可读性方面提出了很多宝贵建议，保证了最终入选文章的准确性和高质量。感谢所有参与 Review 的老师们，感谢所有参与到本次活动每个环节中的小伙伴们。\n\n![TiDB 6.x in action 优秀贡献者.png](https://img1.www.pingcap.com/prod/Ti_DB_6_x_in_action_f88822fd53.png)\n\n![TiDB 6.x in action 荣誉体验官.png](https://img1.www.pingcap.com/prod/Ti_DB_6_x_in_action_846a169065.png)\n\n\n![TiDB 6.x in action 追加作者奖项.png](https://img1.www.pingcap.com/prod/Ti_DB_6_x_in_action_459236ca7d.png)\n\n## 欢迎 TiDBer 们分享 & 持续指正\n\n《TiDB 6.x in Action》所有文章均经过社区多次内容 review，但是我们相信它肯定还存在优化的空间。TiDBer 们在阅读文章的时候，如果发现存在任何语病、或是觉得需要修改的地方、或是觉得描述不够准备的部分，非常欢迎 TiDBer 们以 PR 的形式进行贡献指正。\n\n- 参与方式：GitHub 中 PR 形式提交本次 Book Rush 你觉得需要修改的内容， 并在 **PR 提交正文处注明社区昵称**，截图在活动帖（<https://asktug.com/t/topic/812920>）中回复即可，例如：\n\n![活动参与示意.png](https://img1.www.pingcap.com/prod/_9d6dd9d0bd.png)\n\n- 活动奖励：每个 PR 合入，获得 100 积分&经验值，最高奖励 500 积分&经验值（此活动长期有效，没有截止时间）\n\n再次感谢 TiDBer 们对 TiDB 6.0 Book Rush 的支持，期待下次共创。","date":"2022-07-25","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"book-rush-tidb-6.x-in-action-release","file":null,"relatedBlogs":[{"relatedBlog":{"body":"> 本文源自“TiDB 6.0 Book Rush” 投稿。作者：h5n1，TiDB 爱好者，目前就职于联通软件研究院。\n\n## 前言\n\nTiDB 作为一个分布式数据库，计算节点 tidb server 和存储节点 tikv/tiflash server 有着近乎线性的扩展能力，当资源不足时直接在线扩容即可。但作为整个集群大脑的 PD 节点因为只有 leader 提供服务，不能像其他组件一样通过扩展节点而提高处理能力。\n过往版本 TSO 分配的主要问题：  \n\n1. TSO 分配由 PD Leader 节点提供，大量请求下会导致 Leader 节点 CPU 利用率增高，影响事务延迟。\n2. PD Follower 节点基本处于空闲状态，系统资源利用率较低。\n3. TiDB 跨数据中心访问 PD Leader 时，数据中心间的延迟导致事务延迟增加。\n\n为提升 TSO 的处理性能针对部分场景 TiDB 引入了 TSO Follower Proxy、RC Read TSO 优化、Local TSO 等特性，通过扩展 PD 处理能力和减少 TSO 请求的方式，提升整体吞吐量，降低事务延迟。\n\n## TSO\n\nTSO 是一个单调递增的时间戳，由 PD leader 分配。TiDB 在事务开始时会获取 TSO 作为 start_ts、提交时获取 TSO 作为 commit_ts，依靠 TSO 实现事务的 MVCC。TSO 为 64 位的整型数值，由物理部分和逻辑部分组成，高 48 位为物理部分是 unixtime 的毫秒时间，低 18 位为逻辑部分是一个数值计数器，理论上每秒可产生 262144000（即 2 ^ 18 * 1000）个 TSO。\n\n![TSO.png](https://img1.www.pingcap.com/prod/TSO_62d940cb5c.png)\n\n为保证性能 PD 并不会每次为一个请求生成一个 TSO，而是会预先申请一个可分配的时间窗口，时间窗口是当前时间和当前时间+3 秒后的 TSO，并保存在 etcd 内，之后便可以从窗口中分配 TSO。每隔一定时间就会触发更新时间窗口。当 PD 重启或 leader 切换后会从 etcd 内获取保存的最大 TSO 开始分配，以保证 TSO 的连续递增。\n\n## Follower Proxy\n\n默认情况下 TSO 请求由 PD leader 处理，TiDB 内部通过 PD Client 向 PD leader 发送请求获取 TSO，PD client 并不会将收到的请求立刻发送给 PD leader ，而将同一时刻收到的所有请求打包发送给 PD leader，然后由 PD leader 返回一批 TSO。由于仅有 leader 提供服务，tidb server 数量较多时会有较多的 PD Client 和 PD Leader 建立连接，导致切换处理连接请求时 CPU 消耗较高。同时 follower 节点仅通过 raft 同步数据和提供选举等功能，基本处于空闲状态。  \n\n在 5.3.0 版本引入 TSO Follower Proxy 功能，当开启后 TiDB 的 PD Client 会随机选择一个 PD 节点（包括 leader 和 follower）发送 TSO 请求，PD Follower 会作为一个代理服务将收到的一批请求按照默认情况下 PD Client 处理 TSO 方式打包发送给 leader 处理，以进一步减少 PD Client 和 PD Leader 的交互次数以及 PD leader 的连接数，以此降低 leader 的 CPU 负载。  \n\n![TSO Follower Proxy.png](https://img1.www.pingcap.com/prod/TSO_Follower_Proxy_30f4e79c8e.png)\n\n通过设置全局变量 tidb_enable_tso_follower_proxy 为 true 即可开启 PD follower 的 TSO 代理功能，该功能适用于 tidb server 数量较多并发请求很高，PD leader 因高压力的 TSO 请求而达到 CPU 瓶颈，导致 TSO RPC 请求的延迟较高的场景。\n\n## RC Read TSO 优化\n\nRead-Commited 隔离级别需要在悲观事务模式下，在悲观事务中每个 SQL 执行时会从 PD 获取 TSO (for_update_ts) 用于一致性读、冲突检测等，每个 SQL 相当于一个 Snapshot-Isolation 的’小事务’，相比乐观事务模式悲观事务产生的 TSO 请求会更多，在整个事务期间如果能在不破坏事务一致性和隔离性的情况下减少 tso 请求次数，就能够降低 PD 的负载和事务延迟，从而提升整体性能。  \n\n6.0 版本中对 RC 事务中的 SELECT 语句 TSO 请求做了优化，使用一种乐观方式获取 TSO ，仅当遇到新版本后才会获取最新的 TSO 读取数据，通过减少读操作从 PD 获取 TSO 的请求次数，从而降低查询延迟，提升读写冲突较小场景的 QPS。该特性由 tidb_rc_read_check_ts 变量控制，默认为 off，开启该功能设置为 on 即可。  \n\n优化后 select 语句处理基本过程如下：  \n\n1. Select 语句执行时不从 PD 获取 TSO 作为 for_update_ts，而是使用上一个有效的 TSO 作为 for_update_ts（即为 read_ts）。如果是事务中的第一个语句则是 start_ts，否则是上一个 SQL 的 for_update_ts。\n2. 构建执行计划并执行，发送到 tikv 的数据读取请求（pointget、coprocessor）会带上 RcReadCheckTS 标志。\n3. 数据读取请求使用前面获得的 read_ts 做一致性读取，并将数据返回 tidb server。\n4. TiKV 会检查返回的数据是否有更新版本，如果有更新的版本则返回 WriteConflict 错误，否则返回数据后正常结束执行。\n5. 如果此时 tidb 还未向 client 发送数据则会从 PD 获取最新的 TSO 作为 for_update_ts 重新执行整个查询，否则会向 client 返回错误。  \n\n从上面的过程可以看出遇到新版本会导致 tidb server 使用正常的流程重新获取 TSO 和执行 SQL，在读写冲突的情况下会降低性能使得事务执行时间延长。如果已经有部分数据返回 client 的话会导致报错 SQL 执行失败，虽然通过增加 tidb_init_chunk_size 变量大小延迟 tikv 返回数据时间，可以降低一些上述错误发生的情况，但仍然不是一个根本解决方式。  \n\n## Local TSO\n\n在多数据中心场景下 PD leader 位于某个数据中心内，数据中心间的延迟会造成 TSO 请求延迟增加，如果能够在数据中心内完成 TSO 请求和分配则可以大大降低 TSO 请求延迟。基于此 TiDB 引入了 Local TSO （实验功能），PD 中设计 2 个 TSO allocator 角色：local tso allocator 和 global tso allocator，相应的事务也被分成了本地事务 local transaction 和全局事务 global transaction 两种。  \n\n### Local TSO\n\n当通过 enable-local-tso 启用后数据中心内的 PD 会选出一个节点作为 local tso allocator 用于分配 TSO，该节点作为 local tso 分配的 leader 角色（PD 角色仍为 follower）。当事务操作的数据仅涉及到本数据中心的数据时，则判断为本地事务，向本地 tso allocator 申请 local tso。  \n\n每个数据中心分配自己的 local tso，相互之间是独立的，为避免不同数据中心分配了相同的 TSO，PD 会设置 local tso 中的逻辑时间低几位做后缀，不同的数据中心使用不同的值，同时这些信息会持久化记录到 PD 内。\n\n### Global TSO\n\n当事务操作的数据涉及到其他数据中心时则为全局事务，此时需要向 PD leader 申请 global tso， PD leader 作为 global tso allocator。当未启用 local-tso 功能时，仍按原来的逻辑所有数据中的 TSO 请求由 PD leader 负责处理。  \n\n为保证 local tso 和 global tso 的线性增长，global tso allocator 和 local tso allocator 会进行 max_tso 同步：  \n\n1. Global tso allocator 收集所有 local tso allocator 的最大 local tso。\n2. 从所有 local tso 中选出一个最大的 local tso 作为 max_tso 下发到 local allocator。\n3. 如果 max_tso 比自己的大则更新 TSO 为 max_tso，否则直接返回成功。\n\nLocal tso 的使用需要考虑不同的数据中心处理不同的业务，同时要结合 PlacementRules in SQL 将表根据业务规则按数据中心进行分布，同时可设置 txn_scope 变量为 local/global 用于人为控制获取 global tso 还是 local tso。  \n\n基本配置步骤（目前不支持 Local TSO 回退为 Global TSO 模式）：  \n\n1.PD、TiKV、TiDB server 均需要根据实际部署设置 label，为保证高可用每个 DC 的 PD 数量应>1。\n\n![label 设置 1.jpeg](https://img1.www.pingcap.com/prod/label_1_ab2bdf4afc.jpeg)\n\n![label设置2.jpeg](https://img1.www.pingcap.com/prod/label_2_0c6212e0ec.jpeg)\n\n2.开启库或表级 Placement Rules in SQL，根据地域和业务关系进行调度。  \n\n```\nCREATE PLACEMENT POLICY dc1_leader LEADER_CONSTRAINTS=\"DC1\" FOLLOWER_CONSTRAINTS=\"DC1,DC2,DC3\" FOLLOWERS=2;\nAlter table new_order PARTITION p0  PLACEMENT POLICY dc1_leaders\n```\n3.设置 PD 参数 enable-local-tso=on 使用 tiup reload 重启 PD 开启 Local TSO 功能。启用之后可通过 `pd-ctl -u pd_ip:pd_port member` 中 `tso_allocator_leaders` 项内容查看每个中心的 local tso allocator leader。\n\n![设置 pd 参数.jpeg](https://img1.www.pingcap.com/prod/pd_99fad1fe4f.jpeg)\n\n\n## 测试\n\n### 测试环境\n\n![测试环境.png](https://img1.www.pingcap.com/prod/_66b447f291.png)\n\n### TSO Follower Proxy\n\n在 1024 线程下使用 sysbench 对 6 张 1 亿记录表在开启 TSO Follower Proxy 前后的 TPS 和平均延迟如下：\n\n![sysbench.png](https://img1.www.pingcap.com/prod/sysbench_a559fc6673.png)\n\n测试期间 TSO Follower Proxy 关闭和开启时的 CPU 利用率：  \n\n![CPU 利用率.jpeg](https://img1.www.pingcap.com/prod/CPU_31486267fc.jpeg)\n\n### RC Read TSO\n\n使用 tiup-bench 测试不同线程下开启 tidb_rc_read_check_ts 前后的 TPCC，可以看到开启该功能后对 TPCC 有一定提升，但随着线程数增加冲突增多 TPCC 出现下降情况。\n\n![tiup-bench.png](https://img1.www.pingcap.com/prod/tiup_bench_2a8d585e02.png)\n\n通过 TiDB –> PD Client –> PD Client CMD OPS 监控可以看到 256 线程下开启 tidb_rc_read_check_ts 后 PD client 中等待 TSO 的次数明显降低。\n\n![OPS 监控.png](https://img1.www.pingcap.com/prod/OPS_63d7318b7c.png)\n\n### Local TSO\n\nLocal TSO 作为实验功能尚需完善，TPCC 测试中当开启该功能后出现大量报主键重复错误。\n![local TSO.png](https://img1.www.pingcap.com/prod/local_TSO_bdd1cf8a8e.png)\n\n## 总结\n\n为提升 TSO 的扩展性和效率，TiDB 进行了大量的优化工作，但这些优化有确定的场景，需要结合业务和实际情况考虑，否则盲目开启有可能会造成 QPS 降低、延迟增高的情况：  \n\n1. 对于 Follower TSO Proxy 适合于由于 PD Leader CPU 繁忙导致的 TSO 获取延迟的场景，通过开启 Follower Proxy 后降低 leader 的压力。\n2. RC Read TSO 优化适合于读多写少的场景，如果数据冲突严重反而会造成性能下降。\n3. Local TSO 作为 TiDB 分布式授时方案从理论上能够解决因数据中心间的延迟造成的 TSO 延迟，不过目前实验功能尚有一些问题，将在后续版本不断改进。","author":"h5n1","category":4,"customUrl":"tidb-6.0-make-tso-more-efficient","fillInMethod":"writeDirectly","id":399,"summary":"TSO 是 TiDB 中一个单调递增的时间戳，由 PD leader 分配。TiDB 在事务开始时会获取 TSO 作为 start_ts、提交时获取 TSO 作为 commit_ts，依靠 TSO 实现事务的 MVCC。本文介绍了 TiDB 6.0 版本中对 TSO 分配优化的原理和验证。","tags":["TiDB"],"title":"TiDB 6.0：让 TSO 更高效丨TiDB Book Rush"}},{"relatedBlog":{"body":"> 本文源自“TiDB 6.0 Book Rush” 投稿。作者：啦啦啦啦啦，TiDB 老粉，目前就职于京东物流，社区资深用户。\n\n## 背景\n\n一般情况下使用 TiDB 单表大小为千万级别以上在业务中性能最优，但是在实际业务中总是会存在小表。例如配置表对写请求很少，而对读请求的性能的要求更高。TiDB 作为一个分布式数据库，大表的负载很容易利用分布式的特性分散到多台机器上，但当表的数据量不大，访问又特别频繁的情况下，数据通常会集中在 TiKV 的一个 Region 上，形成读热点，更容易造成性能瓶颈。  \n\nTiDB v6.0.0(DMR) 版本推出了缓存表的功能，第一次看到这个词的时候让我想到了 MySQL 的内存表。MySQL 内存表的表结构创建在磁盘上，数据存放在内存中。内存表的缺点很明显：当 MySQL 启动着的时候，表和数据都存在，当 MySQL 重启后，表结构存在，数据消失。TiDB 的缓存表不存在这个问题。从 asktug 论坛中看到很多小伙伴都很期待缓存表的表现，个人也对它的性能很期待，因此在测试环境中实际看看缓存表的性能如何。\n\n## 缓存表的使用场景\n\n以下部分内容来自官方文档，详情见[缓存表](https://docs.pingcap.com/zh/tidb/v6.0/cached-tables#%E7%BC%93%E5%AD%98%E8%A1%A8)  \n\n> TiDB 缓存表功能适用于以下特点的表：  \n\n- 表的数据量不大\n- 只读表，或者几乎很少修改\n- 表的访问很频繁，期望有更好的读性能\n\n关于第一点官方文档中提到缓存表的大小限制为包含索引在内的所有 key-value 记录的总大小不能超过 64 MB。实际测试使用 Sysbench 生成下文中表结构的表，将数据量从 20w 提高到 30w 后就无法将普通表转换为缓存表，因此生产环境中实际使用缓存表的场景应该最多不超过几十万级别的数据量。关于缓存表对包含读写操作方面的性能，使用多种不同的读写请求比例进行了测试，相较普通表均没有达到更好的性能表现。这是因为为了读取数据的一致性，在缓存表上执行修改操作后，租约时间内写操作会被阻塞，最长可能出现 [tidb_table_cache_lease](https://docs.pingcap.com/zh/tidb/v6.0/system-variables#tidb_table_cache_lease%E4%BB%8E-v600-%E7%89%88%E6%9C%AC%E5%BC%80%E5%A7%8B%E5%BC%95%E5%85%A5) 变量值时长的等待，会导致 QPS 降低。因此缓存表更适合只读表，或者几乎很少修改的场景。\n\n缓存表把整张表的数据从 TiKV 加载到 TiDB Server 中，查询时可以不通过访问 TiKV 直接从 TiDB Server 的缓存中读取，节省了磁盘 IO 和网络带宽。使用普通表查询时，返回的数据量越多索引的效率可能越低，直到和全表扫描的代价接近优化器可能会直接选择全表扫描。缓存表本身数据都在 TiDB Server 的内存中，可以避免磁盘 IO，因此查询效率也会更高。以配置表为例，当业务重启的瞬间，全部业务连接一起加载配置，会造成较高的数据库读延迟。如果使用了缓存表，读请求可以直接从内存中读取数据，可以有效降低读延迟。在金融场景中，业务通常会同时涉及订单表和汇率表。汇率表通常不大，表结构很少发生变化因此几乎不会有 DDL，加上每天只更新一次，也非常适合使用缓存表。其他业务场景例如银行分行或者网点信息表，物流行业的城市、仓号库房号表，电商行业的地区、品类相关的字典表等等，对于这种很少新增记录项的表都是缓存表的典型使用场景。\n\n## 测试环境\n\n### 1. 硬件配置及集群拓扑规划\n\n使用 2 台云主机，硬件配置为 4C 16G 100G 普通 SSD 硬盘。  \n\n![测试环境硬件配置.jpeg](https://img1.www.pingcap.com/prod/_d8c7612ba1.jpeg)\n\n\n### 2. 软件配置\n\n![软件配置.jpeg](https://img1.www.pingcap.com/prod/_45e4a7f540.jpeg)\n\n\n### 3. 参数配置‍\n\n```\nserver_configs:\ntidb:\nlog.slow-threshold: 300\nnew_collations_enabled_on_first_bootstrap: true\n\ntikv:\nreadpool.coprocessor.use-unified-pool: true\nreadpool.storage.use-unified-pool: false\npd:\nreplication.enable-placement-rules: true\n    replication.location-labels:\n    - host\n```\n\n由于硬件条件受限，只有 2 台普通性能的云主机混合部署的集群（实际上和单机部署也差不多了）。单机 CPU 核数较少且 TiDB Server 没有做负载均衡所以并发无法调整太高。以下测试均使用一个 TiDB Server 节点进行压测，因此不用特别关注本次测试的测试数据，可能会跟其他测试结果有所出入，不代表最佳性能实践和部署，测试结果仅限参考。\n\n\n## 性能测试\n\nSysbench 生成的表结构  \n\n```\nCREATE TABLE sbtest1 (\nid int(11) NOT NULL AUTO_INCREMENT,\nk int(11) NOT NULL DEFAULT '0',\nc char(120) NOT NULL DEFAULT '',\npad char(60) NOT NULL DEFAULT '',\nPRIMARY KEY (id),\nKEY k_1 (k)\n) ENGINE = InnoDB CHARSET = utf8mb4 COLLATE = utf8mb4_bin AUTO_INCREMENT = 1\n```\n\n### 读性能测试\n\n**测试主要参数** \n\n**oltp_point_select** 主键查询测试（点查，条件为唯一索引列）  \n\n主要 SQL 语句：  \n\n`SELECT c FROM sbtest1 WHERE id=?`  \n\n**select_random_points** 随机多个查询（主键列的 select in 操作）  \n\n主要 SQL 语句：  \n\n`SELECT id, k, c, pad FROM sbtest1 WHERE k IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`  \n\n**select_random_ranges** 随机范围查询（主键列的 select between and 操作）  \n\n主要 SQL 语句：  \n\n`SELECT count(k) FROM sbtest1 WHERE k BETWEEN ? AND ? OR k BETWEEN ? AND ? OR k BETWEEN ? AND ? OR k BETWEEN ? AND ? OR k BETWEEN ? AND ? OR k BETWEEN ? AND ? OR k BETWEEN ? AND ? OR k BETWEEN ? AND ? OR k BETWEEN ? AND ? OR k BETWEEN ? AND ?`  \n\n**oltp_read_only** 只读操作（包含聚合、去重等）  \n\n主要 SQL 语句：  \n\n```\nSELECT c FROM sbtest1 WHERE id=?\nSELECT SUM(k) FROM sbtest1 WHERE id BETWEEN ? AND ?\nSELECT c FROM sbtest1 WHERE id BETWEEN ? AND ? ORDER BY c\nSELECT DISTINCT c FROM sbtest1 WHERE id BETWEEN ? AND ? ORDER BY c\n```\n\n**Sysbench 测试命令示例**\n\n```\nsysbench --mysql-host=10.0.0.1  --mysql-port=4000  --mysql-db=sbtest --mysql-user=root --time=600 \\\n--threads=8 --report-interval=10 --db-driver=mysql  oltp_point_select --tables=1 --table-size=5000 run\n\nsysbench --mysql-host=10.0.0.1  --mysql-port=4000  --mysql-db=sbtest --mysql-user=root --time=600 \\\n--threads=8 --report-interval=10 --db-driver=mysql  oltp_read_only --tables=1 --table-size=5000 run\n\nsysbench --mysql-host=10.0.0.1  --mysql-port=4000  --mysql-db=sbtest --mysql-user=root --time=600 \\\n--threads=8 --report-interval=10 --db-driver=mysql  select_random_points --tables=1 --table-size=5000 run\n\nsysbench --mysql-host=10.0.0.1  --mysql-port=4000  --mysql-db=sbtest --mysql-user=root --time=600 \\\n--threads=8 --report-interval=10 --db-driver=mysql  select_random_ranges --tables=1 --table-size=5000 run\n```\n\n#### 一、使用普通表\n\n**1.单表数据量 5000，测试 QPS**  \n\n![单表数据量 5000.jpeg](https://img1.www.pingcap.com/prod/5000_0f0ae28fbc.jpeg)\n\n\n**2.单表数据量 50000，测试 QPS**\n\n![单表数据量 50000.jpeg](https://img1.www.pingcap.com/prod/50000_9138032194.jpeg)\n\n\n#### 二、使用缓存表\n\n**1.单表数据量 5000，测试 QPS**\n\n![缓存表单表数据量 5000.jpeg](https://img1.www.pingcap.com/prod/5000_b0f0354e94.jpeg)\n\n\n**2.单表数据量 50000，测试 QPS**\n\n![缓存表单表数据量 50000.jpeg](https://img1.www.pingcap.com/prod/50000_8ec961bb42.jpeg)\n\n\n#### 三、性能对比\n\n![性能对比 1.png](https://img1.www.pingcap.com/prod/1_aa3b00bc28.png)\n\n![性能对比 2.png](https://img1.www.pingcap.com/prod/2_97e1bd1d60.png)\n\n![性能对比 3.png](https://img1.www.pingcap.com/prod/3_1fd558342b.png)\n\n![性能对比 4.png](https://img1.www.pingcap.com/prod/4_5394a76315.png)\n\n\n### 读写混合性能测试\n\n**测试主要场景参数**  \n\noltp_read_write 表示混合读写 \n\npoint_selects（每个事务里点查的数量)  \n\ndelete_inserts（每个事务里插入/删除组合的数量）  \n\n主要 SQL 语句：\n  \n```\nINSERT INTO sbtest1 (id, k, c, pad) VALUES (?, ?, ?, ?)\nDELETE FROM sbtest1 WHERE id=?\nSELECT c FROM sbtest1 WHERE id=?\n```\n\n本次测试通过单个事务中请求类型的数量 --delete_inserts 固定为 10 且调整 --point_selects 参数的值来模拟不同读写比例下的性能差异，其余请求参数使用默认值，具体命令可参考下面 Sysbench 测试命令示例。\n\n**Sysbench 测试命令示例**  \n\n`sysbench --mysql-host=10.0.0.1  --mysql-port=4000  --mysql-db=sbtest --mysql-user=root --time=600 --threads=8 --report-interval=10 --db-driver=mysql  oltp_read_write --tables=1 --table-size=5000   --point_selects=10 --non_index_updates=0 --delete_inserts=10 --index_updates=0 run`\n\n#### 一、使用普通表\n\n**1.单表数据量 5000，测试 QPS**  \n\n![sysbench 单表 5000.jpeg](https://img1.www.pingcap.com/prod/sysbench_5000_27780cb069.jpeg)\n\n\n**2.单表数据量 50000，测试 QPS**  \n\n![sysbench 单表 50000.jpeg](https://img1.www.pingcap.com/prod/sysbench_50000_aea3dbc997.jpeg)\n\n\n#### 二、使用缓存表\n\n**1.单表数据量 5000，测试 QPS**  \n\n![sysbench 缓存表 5000.jpeg](https://img1.www.pingcap.com/prod/sysbench_5000_62ad5d08f1.jpeg)\n\n\n**2.单表数据量 50000，测试 QPS**\n\n![sysbench 缓存表 50000.jpeg](https://img1.www.pingcap.com/prod/sysbench_50000_a59f4f864b.jpeg)\n\n\n#### 三、性能对比\n\n![性能对比01.png](https://img1.www.pingcap.com/prod/01_957950e6f6.png)\n\n![性能对比 02.png](https://img1.www.pingcap.com/prod/02_15384f2fd7.png)\n\n![性能对比 03.png](https://img1.www.pingcap.com/prod/03_683a72430f.png)\n\n![性能对比 04.png](https://img1.www.pingcap.com/prod/04_c61a9551e9.png)\n\n\n## 遇到的问题\n\n- 尝试将 30w 数据的表改为缓存表时报错 。ERROR 8242 (HY000): 'table too large' is unsupported on cache tables。  \n\n目前 TiDB 对于每张缓存表的大小限制为 64 MB，因此太大的表无法缓存在内存中。另外，缓存表无法执行普通的 DDL 语句。若要对缓存表执行 DDL 语句，需要先使用 ALTER TABLE xxx NOCACHE 语句去掉缓存属性，将缓存表设回普通表后，才能对其执行其他 DDL 语句。\n\n- 测试过程中缓存表性能出现了不稳定的情况，有些时候缓存表反而比普通表读取性能差，使用 trace 语句（TRACE SELECT * FROM sbtest1;）查看发现返回结果中出现了regionRequest.SendReqCtx，说明 TiDB 尚未将所有数据加载到内存中，多次尝试均未加载完成。把 tidb_table_cache_lease 调整为 10 后没有出现该问题。\n\n在 asktug 中向研发大佬提出了这个问题得到了解答。根据 <https://github.com/pingcap/tidb/issues/33167> 中的描述，当机器负载较重时，load table 需要 3s 以上 ，但是默认的 tidb_table_cache_lease 是 3s， 表示加载的数据是立即过时的，因此需要重新加载，并且该过程永远重复。导致了浪费了大量的 CPU 资源并且降低了 QPS。目前可以将 tidb_table_cache_lease 的值调大来解决，该问题在 master 分支中已经解决，后续版本应该不会出现。  \n\n- 根据测试结果，写入较为频繁的情况下缓存表的性能是比较差的。在包含写请求的测试中，缓存表相较于普通表的性能几乎都大幅下降。\n\n在 lease 过期之前，无法对数据执行修改操作。为了保证数据一致性，修改操作必须等待 lease 过期，所以会出现写入延迟。例如 tidb_table_cache_lease 为 10 时，写入可能会出现较大的延迟。因此写入比较频繁或者对写入延迟要求很高的业务不建议使用缓存表。\n\n## 测试总结\n\n### 读性能\n\n单表 5000，缓存表相比普通表提升的百分比\n\n![读性能提升.jpeg](https://img1.www.pingcap.com/prod/_3ca95e6878.jpeg)\n\n单表 50000，缓存表相比普通表提升的百分比\n![读性能提升 50000.jpeg](https://img1.www.pingcap.com/prod/50000_013c093d21.jpeg)\n\n### 读写混合\n\n单表 5000，缓存表相比普通表提升的百分比（负增长符合预期）  \n\n![读写混合单表 5000.jpeg](https://img1.www.pingcap.com/prod/5000_4088ab7876.jpeg)\n\n单表 50000，缓存表相比普通表提升的百分比（负增长符合预期）  \n\n![读写混合单表 50000.jpeg](https://img1.www.pingcap.com/prod/50000_fcd5f99a43.jpeg)\n\n\n结果显示，相比于普通表，缓存表在 oltp_point_select、oltp_read_only、select_random_points、select_random_ranges 几种只读的场景下性能有非常大的提升，但在包含写请求的测试中无法提供更好的性能。它的机制决定了使用场景目前仅限于表的数据量不大的只读表，或者几乎很少修改的小表。综上，虽然缓存表目前的使用场景相对比较单一，但是在合适的场景下确实是一个解决了业务痛点的好功能，也期待在后续的版本中能有更高的稳定性和更优秀的性能表现。\n\n","author":"啦啦啦啦啦","category":4,"customUrl":"first-try-of-cached-table-in-tidb-6.0","fillInMethod":"writeDirectly","id":400,"summary":"TiDB v6.0.0 (DMR) 版本推出了缓存表的功能，以应对很少新增记录项的小表上频繁的读请求。在金融场景的订单表、汇率表，银行分行或者网点信息表，物流行业的城市、仓号库房号表，电商行业的地区、品类相关的字典表等等场景下能够很大程度地提高效率。本文通过测试验证了 TiDB 缓存表的性能表现。","tags":["TiDB"],"title":"TiDB v6.0.0 (DMR) ：缓存表初试丨TiDB Book Rush"}},{"relatedBlog":{"body":"> 本文源自“TiDB 6.0 Book Rush” 投稿，作者吴永健。\n\n## 简介\n\nTiDB 6.0 版本正式提供了基于 SQL 接口的[数据放置框架](https://pingcap.com/zh/blog/what-are-placement-rules-in-sql)（Placement Rules in SQL），特性用于通过 SQL 接口配置数据在 TiKV 集群中的放置位置。通过该功能，用户可以将表和分区指定部署至不同的地域、机房、机柜、主机。适用场景包括低成本优化数据高可用策略、保证本地的数据副本可用于本地 Stale Read 读取、遵守数据本地要求等。它支持针对任意数据提供副本数、角色类型、放置位置等维度的灵活调度管理能力，这使得在多业务共享集群、跨 AZ 部署等场景下，TiDB 得以提供更灵活的数据管理能力，满足多样的业务诉求。\n\n该功能可以实现以下业务场景：\n\n- 合并多个不同业务的数据库，大幅减少数据库常规运维管理的成本；\n\n- 增加重要数据的副本数，提高业务可用性和数据可靠性；\n\n- 将最新数据存入 SSD，历史数据存入 HDD，降低归档数据存储成本；\n\n- 把热点数据的 leader 放到高性能的 TiKV 实例上；\n\n- 将冷数据分离到不同的存储中以提高可用性。\n\n![Placement Rules 业务场景.png](https://img1.www.pingcap.com/prod/Placement_Rules_ad3ac60e2d.png)\n\n使用放置规则时有 2 种方式\n\n(1) 直接放置\n\n直接放置是指在 create table 时或使用 alter table 方式直接在表的 DDL 语句中使用放置选项\n\n`create table jian(id int) primary_region='bj' folllowers=4`\n\n(2) 放置策略\n\n使用放置策略时首先通过 create placement policy 建立放置策略，然后在 create table 或 alter table 中直接指定放置策略。\n\n```\ncreate placement policy location_policy primary_region='bj' folllowers=4;\nalter table jian placement policy location_policy;\n```\n\n使用时：创建放置策略会使 placement policy 更加易于管理，通过修改放置策略可以直接更新所有使用该策略的对象。另一方面对于 create table 时使用和 alter table 时指定，这里也建议大家能注意以下两点：\n\n1. create 方式建议在项目初期的库表结构设计节点进行设定，那么在初始话项目数据库的时候可以一次成型。否则需要将整个表进行 recreate，此处就需要考虑历史数据的问题。\n\n2. alter 方式由于是使用 ALTER 进行修改当表数据量大的时候可能会产生大量数据 peer 的移动，可能会消耗一定的资源，建议在业务低峰进行，但是也较好地弥补了一些即存表没有进行放置规则的设定后期需要添加，或者版本升级后需要使用新特性的问题。\n\n### Placement Rules in SQL 的应用场景猜想\n\n由于 Placement Rules in SQL 的灵活性，在使用时可以“因地适宜”。以下是几个可以考虑的场景：\n\n1. 当采取两地三中心或跨地域数据中心部署的时候，由于 TiDB 是无状态的应用那么可以利用就近原则将业务接入点进行分块，同时对于数据的分布也可以采用同样的方式。使数据的存放可以达到“本地数据本地访问”，即所有的数据存储，管理在本地区内完成。减少了数据跨地区复制延迟，降低流量成本。\n\n2. 当系统  IO 存在某些瓶颈时可以考虑将某些 TiKV 节点的数据盘更换为 SSD，之后经过 Placement Rules 动态调整数据副本的存放策略，提高数据库的 IO 性能。对于一些历史及记录类的数据可以选择存放在一些主要由普通硬盘构成的 TiKV 节点上。使硬件资源的配置得到充分的利用，而又不铺张浪费。\n\n3. 同时也考虑当进行硬件更换时可以使用 Placement Rules 对数据分布进行调整以减小 TiKV 节点下线时的 peer 移动所需要的时间，因为通过 Placement Rules 可以将数据移动的动作提前进行分散在平时的小维护中。\n\n4. 由于数据的重要程度不同对于以往的副本设置可能更偏向于全局，引入 Placement Rules in SQL 后对于数据的副本数就可以进行灵活的限定，对高要求的数据表进行多副本设置，对于不太紧要的表尽量的减小副本数，在保证数据的安全性的情况下又可以节约存储资源。\n\n5. 如果业务采用了分库的模式为了减少运维成本，那么也可以考虑进行数据库整合，将分散的 MySQL 实例迁移到一个 TiDB 集群中以多 schema 的方式存在，同时根据 Placement Rules 原始业务数据库的数据存放节点仍然可以放置在原来的硬件节点上，但是逻辑上由于整合到了一个数据库集群中升级、打补丁、备份计划、扩缩容等日常运维管理频率可以大幅缩减，降低管理负担提升效率。\n\n6. 对于经典的热点问题在 Placement Rules in SQL 也添加了更多的解决方案，通过 Placement Rules in SQL 也可以进行热点表的分布调整，而且也更加的方便与安全。虽然不能精确到 Region 的级别，但是在表的粒度上也多提供了一种处理方法。\n\n下面我们来详细看看 placement policy 的使用方法：\n\n当前 TiKV 节点以及集群的信息如下：\n```\nID                     Role          Host             Ports        OS/Arch       Status   Data Dir                      Deploy Dir\n\n\\--                     ----          ----             -----        -------       ------   --------                      ----------\n\n192.168.135.148:9093   alertmanager  192.168.135.148  9093/9094    linux/x86_64  Up       /tidb-data/alertmanager-9093  /tidb-deploy/alertmanager-9093\n\n192.168.135.148:3000   grafana       192.168.135.148  3000         linux/x86_64  Up       -                             /tidb-deploy/grafana-3000\n\n192.168.135.148:2379   pd            192.168.135.148  2379/2380    linux/x86_64  Up|L|UI  /tidb-data/pd-2379            /tidb-deploy/pd-2379\n\n192.168.135.148:9090   prometheus    192.168.135.148  9090/12020   linux/x86_64  Up       /tidb-data/prometheus-9090    /tidb-deploy/prometheus-9090\n\n192.168.135.148:4000   tidb          192.168.135.148  4000/10080   linux/x86_64  Up       -                             /tidb-deploy/tidb-4000\n\n192.168.135.148:20160  tikv          192.168.135.148  20160/20180  linux/x86_64  Up       /tidb-data/tikv-20160         /tidb-deploy/tikv-20160\n\n192.168.135.148:20161  tikv          192.168.135.148  20161/20181  linux/x86_64  Up       /tidb-data/tikv-20161         /tidb-deploy/tikv-20161\n\n192.168.135.148:20162  tikv          192.168.135.148  20162/20182  linux/x86_64  Up       /tidb-data/tikv-20162         /tidb-deploy/tikv-20162\n```\n\n![640.png](https://img1.www.pingcap.com/prod/640_d13581db8a.png)\n\n这里有一点需要大家注意一下：**默认的 PLACEMENT POLICY 是需要以 region 来作为区分标签的，所以在创建 TiKV 的时候这里需要明确的指定 TiKV 的 region 的标签，不然的话在show placement labels 时是无法看到 region lable 的。这里可以参照[官方文档](https://docs.pingcap.com/zh/tidb/stable/placement-rules-in-sql)的建议**。\n\n## PLACEMENT RULES 的使用\n\n### 创建 PLACEMENT POLICY，并指定 PLACEMENT POLICY，定制其副本放置的位置\n\n这里创建一个 PLACEMENT POLICY 使其  PRIMARY_REGION 放置在 region lable 为 bj 的 tikv 节点上，其余副本放置在 region lable 为 dl,sz 的 tikv 节点上\n\n注意：**primary region 必须包含在 region 的定义中**\n\n**此处的 Raft leader 在 4 号 store 上，看之前开头的环境信息可以验证 PLACEMENT POLICY 已经生效**\n\n```\n(root\\@127.0.0.1) \\[test] 12:00:14> CREATE PLACEMENT POLICY jianplacementpolicy PRIMARY_REGION=\"bj\" REGIONS=\"bj,dl,sz\";\n\nQuery OK, 0 rows affected (0.10 sec)\n\n(root\\@127.0.0.1) \\[test] 12:00:32> CREATE TABLE jian1 (id INT) PLACEMENT POLICY=jianplacementpolicy;\n\nQuery OK, 0 rows affected (0.10 sec)\n\n(root\\@127.0.0.1) \\[test] 12:03:36> show table jian1 regions\\G\n\nREGION_ID: 135\n\nSTART_KEY: t_68\\_\n\nEND_KEY: t_69\\_\n\nLEADER_ID: 137\n\nLEADER_STORE_ID: 4    这里可以看到store_id是4                                \n\nPEERS: 136, 137, 138\n\nSCATTERING: 0\n\nWRITTEN_BYTES: 39\n\nREAD_BYTES: 0\n\nAPPROXIMATE_SIZE(MB): 1\n\nAPPROXIMATE_KEYS: 0\n\n1 row in set (0.00 sec)\n```\n\n### 创建表不指定 PLACEMENT POLICY，之后修改 PLACEMENT POLICY 定制其副本放置的位置\n\n**leader 的 store 节点由原来的 1 变为了 4，看之前开头的环境信息可以验证 PLACEMENT POLICY 已经生效,可使用这个特性来修改表的 leader 节点或者当有热点问题时也可以变相的通过这种方式去修改频繁访问的表的 leader 所在的 tikv 的节点位置**\n\n```\n(root\\@127.0.0.1) \\[test] 12:03:39> create table jian2(id int);\n\nQuery OK, 0 rows affected (0.10 sec)\n\n(root\\@127.0.0.1) \\[test] 12:05:14> show table jian2 regions\\G\n\n\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\* 1. row \\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\n\nREGION_ID: 2\n\nSTART_KEY: t_70\\_\n\nEND_KEY:\n\nLEADER_ID: 3\n\nLEADER_STORE_ID: 1\n\nPEERS: 3, 63, 85\n\nSCATTERING: 0\n\nWRITTEN_BYTES: 0\n\nREAD_BYTES: 0\n\nAPPROXIMATE_SIZE(MB): 1\n\nAPPROXIMATE_KEYS: 0\n\n1 row in set (0.00 sec)\n\n(root\\@127.0.0.1) \\[test] 12:05:16> alter table jian2  PLACEMENT POLICY=jianplacementpolicy;\n\nQuery OK, 0 rows affected (0.09 sec)\n\n(root\\@127.0.0.1) \\[test] 12:05:50>  show table jian2 regions\\G\n\n\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\* 1. row \\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\n\nREGION_ID: 143\n\nSTART_KEY: t_70\\_\n\nEND_KEY: t_71\\_\n\nLEADER_ID: 145\n\nLEADER_STORE_ID: 4                       \n\nPEERS: 144, 145, 146\n\nSCATTERING: 0\n\nWRITTEN_BYTES: 0\n\nREAD_BYTES: 0\n\nAPPROXIMATE_SIZE(MB): 1\n\nAPPROXIMATE_KEYS: 0\n\n1 row in set (0.00 sec)\n```\n\n### 通过  PLACEMENT POLICY 修改表的副本数\n\n> Follower 的数量。例如 FOLLOWERS=2 表示数据有 3 个副本（2 个 follower 和 1 个 leader）。\n\n```\n(root\\@127.0.0.1) \\[test] 12:10:34> alter  PLACEMENT POLICY jianplacementpolicy FOLLOWERS=1;\n\nQuery OK, 0 rows affected (0.11 sec)\n\n(root\\@127.0.0.1) \\[test] 12:10:40>  show table jian2 regions\\G\n\n\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\* 1. row \\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\n\nREGION_ID: 143\n\nSTART_KEY: t_70\\_\n\nEND_KEY: t_71\\_\n\nLEADER_ID: 145\n\nLEADER_STORE_ID: 4\n\nPEERS: 144, 145                    **副本数从 3 个已经调整到了 2 个\n**\n\nSCATTERING: 0\n\nWRITTEN_BYTES: 0\n\nREAD_BYTES: 0\n\nAPPROXIMATE_SIZE(MB): 1\n\nAPPROXIMATE_KEYS: 0\n\n1 row in set (0.00 sec)\n\n(root\\@127.0.0.1) \\[test] 12:10:44> alter  PLACEMENT POLICY jianplacementpolicy FOLLOWERS=2;\n\nQuery OK, 0 rows affected (0.09 sec)\n\n(root\\@127.0.0.1) \\[test] 12:10:59>  show table jian2 regions\\G\n\n\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\* 1. row \\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\n\nREGION_ID: 143\n\nSTART_KEY: t_70\\_\n\nEND_KEY: t_71\\_\n\nLEADER_ID: 145\n\nLEADER_STORE_ID: 4\n\nPEERS: 144, 145, 148\n\nSCATTERING: 0\n\nWRITTEN_BYTES: 0\n\nREAD_BYTES: 0\n\nAPPROXIMATE_SIZE(MB): 1\n\nAPPROXIMATE_KEYS: 0\n\n1 row in set (0.02 sec)\n```\n\n![641.png](https://img1.www.pingcap.com/prod/641_9ed75cce40.png)\n\n![642.png](https://img1.www.pingcap.com/prod/642_85f25431cd.png)\n\n### 修改 PLACEMENT POLICY 定义\n\n**注意：修改定义时需要将原来的定义都带上否则会将其覆盖**。\n\n这一点在官方文档中并没有特殊说明，也是自己在测试这个功能的时候偶然的发现，目前官方也没有直接修改的语法，所以大家在修改放置规则的时候一定要注意之前的定义以免将之前的定义覆盖。\n\n![643.png](https://img1.www.pingcap.com/prod/643_27204a572a.png)\n\n```\n##########################################################\n之前的 PRIMARY_REGION=\"bj\" REGIONS=\"bj,dl,sz\" 定义已经被覆盖了\n##########################################################\n```\n\n### PRIMARY_REGION 节点宕机\n\n**如果 PRIMARY_REGION 的 TiKV 节点宕机，那么 leader 节点也会转移到非 PRIMARY_REGION 节点，当 TiKV 节点恢复正常后 leader 节点也会随之转移回来**\n\n以下的过程\n\n> leader 节点：store4--  停止 store 的 tikv   ---> store1 --  恢复 tikv 节点-- > store4   \n\n![644.png](https://img1.www.pingcap.com/prod/644_f552f18a8c.png)\n\n![645.png](https://img1.www.pingcap.com/prod/645_98ea6ca9b5.png)\n\n### 更改 PRIMARY_REGION\n\n**如果更改表当前 palcement policy 定义的 primary region 那么表的 leader 也会随 PRIMARY_REGION 的改变而改变**\n\n> 下图 jian1 表一开始的 region 1005 的 leader 是在 store4（bj）上边，之后修改其 PRIMARY_REGION 为 dl(store 1)，可以看到 region 1005 的 leader 也确实随之发生了改变\n\n![646.png](https://img1.www.pingcap.com/prod/646_5898827ed0.png)\n\n### PLACEMENT POLICY 同样适用与分区表\n\n**以下样例中我们手动指定了每一个分区的 PLACEMENT POLICY，使其每个分区的 leader 都存放于不同的 store 上**。\n\n```\nCREATE PLACEMENT POLICY policy_table FOLLOWERS=3;\n\nCREATE PLACEMENT POLICY policy_dl PRIMARY_REGION=\"dl\" REGIONS=\"dl,bj,sz\";\n\nCREATE PLACEMENT POLICY policy_bj PRIMARY_REGION=\"bj\" REGIONS=\"dl,bj,sz\";\n\nCREATE PLACEMENT POLICY policy_sz PRIMARY_REGION=\"sz\" REGIONS=\"dl,bj,sz\" FOLLOWERS=1;\n\nSET tidb_enable_list_partition = 1;\n\nCREATE TABLE t1 (\n\nlocation VARCHAR(10) NOT NULL,\n\nuserdata VARCHAR(100) NOT NULL\n\n) PLACEMENT POLICY=policy_table PARTITION BY LIST COLUMNS (location) (\n\nPARTITION p_dl VALUES IN ('dl') PLACEMENT POLICY=policy_dl,\n\nPARTITION p_bj VALUES IN ('bj') PLACEMENT POLICY=policy_bj,\n\nPARTITION p_sz VALUES IN ('sz') PLACEMENT POLICY=policy_sz\n\n);\n```\n\n下图可以看到 t1 的 region 分别存放在 store 1(dl),4(bj),5(sz) 上边\n\n![647.png](https://img1.www.pingcap.com/prod/647_f96eb83549.png)\n\n### 查看数据库中现有的 PLACEMENT POLICY\n\n![648.png](https://img1.www.pingcap.com/prod/648_21aee6ed8b.png)\n\n### 设置数据库级别的 PLACEMENT POLICY\n\n> 更改默认的放置选项，但更改不影响已有的表  \n创建新表会自动继承当前数据的放置规则  \n表级别的放置规则要优先于数据库级别的放置规则\n\n![649.png](https://img1.www.pingcap.com/prod/649_eafb783685.png)\n\n### 高级放置规则\n\n**注意：PRIMARY_REGION、REGIONS 和 SCHEDULE 选项不可与 CONSTRAINTS 选项同时指定，否则会报错**。\n\n**以下 placement policy 的解读为**：\n\n1. 使用该规则的表的 region 只可以放置在含有 rack 标签且等于 rack1 的 tikv 节点上；\n\n2. 使用该规则的表的 leader region 只可以放置在含有 dc 标签且等于 bja 的 tikv 节点上；\n\n3. 使用该规则的表的 follower region 只可以放置在含有 dc 标签且等于 dla 的 tikv 节点上。\n\n```\n(root\\@127.0.0.1) \\[(none)] 16:34:28>  create placement policy localtion_policy CONSTRAINTS=\"\\[+rack=rack1]\" LEADER_CONSTRAINTS=\"\\[+dc=bja]\" FOLLOWER_CONSTRAINTS=\"{+dc=dla: 1}\";\n\nQuery OK, 0 rows affected (0.10 sec)\n\n(root\\@127.0.0.1) \\[(none)] 16:35:41> create table testdb.jian2(id int) placement policy=localtion_policy;\n\nQuery OK, 0 rows affected (0.19 sec)\n\n(root\\@127.0.0.1) \\[(none)] 16:35:49> show table testdb.jian2 regions\\G\n\n\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\* 1. row \\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\n\nREGION_ID: 1127\n\nSTART_KEY: t_167\\_\n\nEND_KEY: t_168\\_\n\nLEADER_ID: 1129\n\nLEADER_STORE_ID: 4\n\nPEERS: 1128, 1129\n\nSCATTERING: 0\n\nWRITTEN_BYTES: 0\n\nREAD_BYTES: 0\n\nAPPROXIMATE_SIZE(MB): 1\n\nAPPROXIMATE_KEYS: 0\n\n1 row in set (0.01 sec)\n```\n\n注意：虽然 placement policy 高级匹配规则的默认 followers 是 2（三副本）但是实际的副本数还是要看符合 lable 的 tikv 的数量,如果实际的 tikv 节点数量无法满足 2followers 那么最终也只会有两个副本（也就是只有一个 followers 和一个 leader）上边的查询结果可以看到实际 region 的副本只有两个，但是当查询 localtion_policy  这个规则定义的时候 followers 为 2。\n\n```\nPOLICY_ID: 17\n\nCATALOG_NAME: def\n\nPOLICY_NAME: localtion_policy\n\nPRIMARY_REGION:\n\nREGIONS:\n\nCONSTRAINTS: \\[+rack=rack1]\n\nLEADER_CONSTRAINTS: \\[+dc=bja]\n\nFOLLOWER_CONSTRAINTS: {+dc=dla: 1}\n\nLEARNER_CONSTRAINTS:\n\nSCHEDULE:\n\nFOLLOWERS: 2\n\nLEARNERS: 0\n```\n\n### placement policy 的创建选项\n\n| 选项名| 描述 |\n|:----|:---- |\n| PRIMARY_REGION\t| Raft leader 被放置在有 region 标签的节点上，且这些 region 标签匹配本选项的值。| \n| REGIONS\t| Raft followers 被放置在有 region 标签的节点上，且这些 region 标签匹配本选项的值。| \n| SCHEDULE\t| 用于调度 follower 放置位置的策略。可选值为 EVEN（默认值）或 MAJORITY_IN_PRIMARY。| \n| FOLLOWERS\t| Follower 的数量。例如 FOLLOWERS=2 表示数据有 3 个副本（2 个 follower 和 1 个 leader）。| \n| CONSTRAINTS\t| 适用于所有角色 (role) 的约束列表。例如，CONSTRAINTS=\"[+disk=ssd]\"。| \n| LEADER_CONSTRAINTS\t| 仅适用于 leader 的约束列表。| \n| FOLLOWER_CONSTRAINTS\t| 仅适用于 follower 的约束列表。| \n| LEARNER_CONSTRAINTS\t| 仅适用于 learner 的约束列表。| \n| LEARNERS \t| 指定 learner 的数量。| \n\n\n### 删除 placement policy\n\n删除 placement policy 时一定要确保没有任何表在使用当前的 placement policy 否则会报错：\n\n```\n(root\\@127.0.0.1) \\[test] 12:11:43> drop PLACEMENT POLICY jianplacementpolicy;\n\nERROR 8241 (HY000): Placement policy 'jianplacementpolicy' is still in use\n\n(root\\@127.0.0.1) \\[test] 12:16:20> alter table jian1 PLACEMENT POLICY=default;\n\nQuery OK, 0 rows affected (0.08 sec)\n```\n\n查看某个 placement policy 是否正在被表使用：\n\n```\nSELECT table\\_schema, table\\_name FROM information\\_schema.tables WHERE tidb\\_placement\\_policy\\_name='jianplacementpolicy';\n\nSELECT table\\_schema, table\\_name FROM information\\_schema.partitions WHERE tidb\\_placement\\_policy\\_name='jianplacementpolicy';\n```\n\n## 总结\n\n当前版本在使用 Placement Rules in SQL 时如果使用基本的放置规则那么只可以使用   PRIMARY_REGION 和 REGIONS 来进行放置规则的设置，但是如果使用高级放置规则那么 tikv 的 label 标签不需要必须设置 region 层级的标签，可以灵活使用和定义已存在或者需要的标签。\n\n高级放置规则的默认 followers 的数量为 2，但是如果在设置规则 FOLLOWER_CONSTRAINTS 时如果满足的节点不满足 2 时只会在 FOLLOWER_CONSTRAINTS 匹配的节点上创建副本，这一点在创建时一定要规划好自己的集群中的 tikv 节点的标签设计，以免导致 region 的副本数过少。\n\nPlacement Rules in SQL 可以通过它对分区 / 表 / 库不同级别的数据进行基于标签的自由放置。\n\n总之 TiDB 6.0 的 Placement Rules In SQL 暴露了以往用户无法控制的内部调度能力，并提供了方便的 SQL 接口，这开启了诸多以往不可能实现的场景，更多的运用方式与使用场景还期待各位的发掘。\n\n","author":"吴永健","category":4,"customUrl":"practice-of-placement-rules-in-sql","fillInMethod":"writeDirectly","id":411,"summary":"本文简要介绍了 Placement Rules in SQL 的应用场景，并通过一个例子详细介绍了 placement policy 的使用方法。","tags":["TiDB"],"title":"TiDB Placement Rules in SQL 使用实践丨TiDB Book Rush"}}]},{"id":"Blogs_397","title":"应用开发者专属的 TiDB 使用指南发布啦！丨TiDB Community","tags":["TiDB"],"category":{"name":"社区动态"},"summary":"对于使用 TiDB 的应用开发者来说，需要一份告诉大家如何能像使用 MySQL 一样使用 TiDB 的操作手册。我们编写了全新的 Developer Guide，这份文档可以帮助应用开发者，在最短时间内上手 TiDB。","body":"随着 TiDB 的使用群体进一步扩大，TiDB 的文档也面临着更加多样性的挑战。之前的文档主题主要集中于 TiDB 的部署和运维，但对于使用 TiDB 的应用开发者来说，更需要一份能像使用 MySQL 一样使用 TiDB 的操作手册，同时还能够把乐观事务、Sequence、HTAP 等 TiDB 的独有特性用起来。\n\n因此，我们编写了全新的 [Developer Guide](https://docs.pingcap.com/zh/tidb/stable/dev-guide-overview)，这份文档可以帮助应用开发者，在最短时间内上手 TiDB。在文档中，我们也阐述了应用开发者最常见的一些问题，例如：savepoint 特性的不兼容，TiDB 乐观事务使用时需要如何进行错误处理等。\n\n另外，我们也为应用开发者进行了特殊优化和场景定制。例如，为不便自行运维的开发者，提供了 TiDB Cloud 集群使用方式；为本地不便部署 TiDB 或开发 SDK 环境的开发者，提供了 Gitpod 云原生开发环境的使用帮助。\n\n## 如何使用 Developer Guide\n\n在我们的设想中，Developer Guide 非常适合但不限于以下这些场景的使用：\n- 你是一个应用开发者，有编程语言基础，但对数据库一无所知，准备选择一个 NewSQL 数据库进行学习或使用；\n- 你是一个应用开发者，有编程语言和传统关系型数据库（如 MySQL、PostgreSQL）的基础，准备选择一个 NewSQL 数据库进行学习或使用；\n- 你是一个应用开发者，你的公司或组织已经部署了 TiDB，需要你基于 TiDB 来编写一个可靠的应用程序；\n- 你是一个应用开发者，你已经基于 TiDB 来编写了一个应用程序，但出现了故障，你需要排查故障；\n- 你是一个语言学习者，你希望使用编程语言配合 NewSQL 数据库进行大数据量的读写尝试。\n\n## Developer Guide 中包含哪些内容？\n\n对于数据库零基础的应用开发者，Developer Guide 中包含了应用开发者需要了解的 TiDB 细节，如数据库设计、事务、数据读写的最佳实践，同时还附上了丰富的应用源码示例，帮助你零基础入门 TiDB；对于有 MySQL 基础的应用开发者，Developer Guide 中详细描述了 TiDB 与 MySQL 之间的差别，帮助你快速过渡到新一代 NewSQL 数据库的使用；对于已经在工作中使用 TiDB 的开发者，Developer Guide 中丰富的应用源码示例和故障诊断案例，也能帮助你提高 TiDB 的开发效率。\n\n除了 TiDB 本身相关的内容，我们也编写了一些你在写应用程序时需要注意的细节，比如在 Java 中使用 JDBC Connector 的细节等。同时，Developer Guide 中还屏蔽了应用开发者无需关心的 TiDB 细节，如 TiDB 的 GC、调度、集群部件的配置等。\n\n以下是 Developer Guide 的主要内容：\n- 概览：通篇介绍整体开发文档；\n- 快速开始：如何使用 Java 或者 Golang 语言构建应用程序；\n- 示例程序：如何使用 Spring Boot 和 TiDB 集群，构建一个 HTTP 服务；\n- 连接到 TiDB：连接到 TiDB 数据库时需要注意什么，连接池的最大连接数大小怎么配置；\n- 数据库模式设计：如何在使用 TiDB 设计数据库时避免大多数的错误。TiDB 中有什么在特定场景可以大幅提升性能的特性；\n- 数据写入、数据读取：读密集和写密集的表，如何设置才能性能最大化。批量操作，如何才能不踩坑；\n- 事务： TiDB 的事务有什么特点，和 MySQL 何不同；\n- 优化 SQL 性能：在 TiDB 中，如何让你的 SQL 跑得更快；\n- 故障诊断：在发生故障时，如何快速定位并修复；\n- 云原生开发环境：如何免费使用云原生的开发环境（Gitpod）编写程序，免于本地部署开发环境；\n\n可以看到，整个文档是以示例驱动的。[Java 示例](https://github.com/pingcap-inc/tidb-example-java)，和 [Golang 示例](https://github.com/pingcap-inc/tidb-example-golang)是整个文档的创作核心，文档中的所有的代码片段都是经过测试的。基于这些示例，应用开发者可以在最短的时间内上手 TiDB，无需漫长的学习周期和过高的上手门槛，就能简单快捷地在自己的程序中使用 TiDB。通过这些示例，应用开发者还可以快速了解 TiDB 的能力，比如 TiDB 可以完成的工作、最佳场景、不支持的特性等。\n\n## 简单 CRUD 应用程序\n因为 TiDB 兼容 MySQL，所以在成功部署 TiDB 集群之后，开发者可以使用 MySQL 客户端连接 TiDB，并且[大多数情况下](https://docs.pingcap.com/zh/tidb/stable/mysql-compatibility)可以直接执行 MySQL 语句。在 Developer Guide 中，对于基础的 CURD SQL 也进行了简要的介绍，比如在[使用 TiDB 的增删改查 SQL](https://docs.pingcap.com/zh/tidb/stable/dev-guide-tidb-crud-sql) 一文中，我们着重介绍了 SQL 中，和应用开发者关系最紧密的 DML（Data Manipulation Language，数据操作语言） 和 DQL（Data Query Language，数据查询语言） 部分。\n\n## Gitpod 快速体验 TiDB\n\n对于不便部署本地开发环境的开发者，我们也提供了 Gitpod 云原生开发环境的使用帮助。Gitpod 是 Github 推出的云原生开发环境，基于它可以直接在浏览器上编辑代码并运行。甚至直接部署你的服务到 Gitpod 的机器上，开放端口并远程访问它。\n\n![2.png](https://img1.www.pingcap.com/prod/2_1fe84bc7b0.png)\n\n\n我们基于 Gitpod，为没有条件部署 TiDB 或开发 SDK 环境的开发者，提供了一个 TiDB [Golang 示例](https://gitpod.io/#targetMode=gorm/https://github.com/pingcap-inc/tidb-example-golang)，打开这个链接，你就可以直接从你的浏览器或桌面 IDE 启动一个远程的 TiDB 开发环境，快速体验 TiDB 的能力。\n\n## 更新计划\n未来我们计划编写更多的语言 / 驱动 / ORM 的示例，帮助更多的应用开发者把 TiDB 用起来。如果你对 Developer Guide 有任何改进建议，也欢迎反馈给我们。可以通过 Github issue 来提交反馈：\n- 中文文档：[https://github.com/pingcap/docs-cn/issues](https://github.com/pingcap/docs-cn/issues)\n- 英文文档：[https://github.com/pingcap/docs/issues](https://github.com/pingcap/docs/issues)","date":"2022-06-22","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"new-tidb-developer-guide-is-coming","file":null,"relatedBlogs":[]},{"id":"Blogs_371","title":"TiDB 6.0 发版：向企业级云数据库迈进","tags":["TiDB","Release"],"category":{"name":"社区动态"},"summary":"2022 年 4 月 7 日，TiDB 6.0 发版。在该版本中，我们大幅度加强了作为企业级产品的可管理性，与此同时也加入了诸多云原生数据库所需的基础设施，让 TiDB 在成熟的企业级云数据库维度更向前迈进。","body":"![TiDB 6.0.jpeg](https://img1.www.pingcap.com/prod/Ti_DB_6_0_67ed961868.jpeg)\n\n## 概览\n\n我们很高兴为大家带来 TiDB 最新版 6.0 的介绍。虽然是一个开源数据库，但 TiDB 的定位一直都是面向企业级和云的数据库，而 TiDB 6.0 也是围绕这个主题而研发的。在最新版本中，我们大幅度加强了作为企业级产品的可管理性，与此同时也加入了诸多云原生数据库所需的基础设施。\n\n对于企业级和云数据库，除了性能，可用性和功能等常规维度外，一个重要维度就是可管理性。除了提供必备的「硬」能力以完成用户的技术及业务目标，是否「好用」，是用户做选择时的重要考量，可管理性维度也会很深地影响用户实际使用数据库的隐性成本。而这点对于云数据库则更为明显，将数据库作为云服务提供，将使得可管理性的重要程度被放大：一个可运维性更好的数据库，在固定的运维和支持资源下，将为用户提供更好的服务。\n\n针对这个方向，TiDB 6.0 引入数据放置框架（Placement Rules In SQL），增加了企业级集群管理组件 TiDB Enterprise Manager ，开放了智能诊断服务 PingCAP Clinic 的预览，大幅加强了生态工具的可运维性，并针对热点问题为用户提供了更多的手段。这些努力加在一起，将使用户无论使用的是公有云服务，还是私有部署，都获得体验更平滑和近似的使用体验，让 TiDB 在成熟的企业级云数据库维度更向前迈进。\n\n除此之外，在这一年的时间内 TiDB 6.0 相较于前序版本也有了长足的进步，修复了 137 个 Issues，并融入了 77 个严苛的真实环境锤炼带来的增强。而社区一直期望的 [TiFlash 开源](https://github.com/pingcap/tiflash)也实现了，欢迎广大社区开发者一起参与。\n\n<div class=\"is-flex is-flex-direction-row is-justify-content-center\">\n  <div class=\"is-flex is-flex-direction-column\">\n    <a target=\"_blank\" class=\"button is-link mx-5\"\n       href=\"https://pingcap.com/zh/product-community/\"\n       style=\"background-color: #4fc172;\">\n      下载 TiDB 社区版\n    </a>\n  </div>\n  <div class=\"is-flex is-flex-direction-column\">\n    <a target=\"_blank\" class=\"button is-link mx-5\"\n       href=\"https://pingcap.com.cn\"\n       style=\"background-color: #3a40e1;\">\n      了解 TiDB 企业版\n    </a>\n  </div>\n  <div class=\"is-flex is-flex-direction-column\">\n    <a target=\"_blank\" class=\"button is-link mx-5\"\n       href=\"https://tidbcloud.com/free-trial?utm_source=website-zh&utm_medium=referral&utm_campaign=blog-tidb-6.0-release\"\n       referrerpolicy=\"no-referrer-when-downgrade\" style=\"background-color: #3a40e1;\">\n      免费试用 TiDB Cloud\n    </a>\n    <div style=\"font-size:12px; text-align:center\">适用于中国出海企业和开发者</div>\n  </div>\n</div>\n\n## 全面加强可管理性\n\n可管理性是数据库的一个重要能力维度：在满足业务需求的前提下，是否灵活易用，将决定了用户技术选择背后的隐性成本。这种成本可大可小，可以是一句抱怨，也可能会结合人因带来灾难性后果。在最新版本研发过程中，我们结合了客户和市场反馈，总结了当前的可管理性的问题仍存在的缺失，这包含了「复杂且不直观的集群的日常管理」、「无法控制数据的存储位置」、「数据生态套件难于使用」、「面对热点缺少解决方案」等多个维度，而 TiDB 6.0 从内核、数据生态套件、增强组件多个方面针对这些问题进行了加强。\n\n### 自主的数据调度框架\n\n让我们先从内核部分开始。\n\nTiDB 6.0 以 SQL 形式对用户暴露数据调度框架（Placement Rule In SQL）。以往，TiDB 的数据调度对于用户一直都是黑盒，TiDB 自行决定某一个数据块应该存在哪个节点，无论数据中心的物理边界和不同规格机器差异。这使得 TiDB 在多中心，冷热数据分离和大量写入所需的缓冲隔离等场景下无法提供灵活的应对。\n\n我们先看两个有趣的场景：\n\n1. 你有一个业务横跨多个城市，北京、上海和广州都设有数据中心。你希望将 TiDB 以跨中心的方式部署在这三个数据中心，分别覆盖华北、华东和华南的用户群，让不同区域的用户可以就近访问数据。在以往的版本中，用户的确可以跨中心的方式部署 TiDB 集群，但却无法如上述期望地将归属不同用户群的数据存放在不同的数据中心，只能任由 TiDB 按照热点和数据量均匀分布的逻辑将数据分散在不同中心。在高频访问的情况下，用户访问很可能会频繁跨越地域进而承受很高的延迟。\n\n2. 你希望用一组导入专用节点专门用于隔离导入数据所带来的性能抖动，而后再将导入完的数据迁回工作节点；或者你希望用一组低配节点存放冷数据，接受低频历史数据访问。暂时，还没有特别的手段支持这样的用况。\n\nTiDB 6.0 开放的数据调度框架提供了针对分区 / 表 / 库级数据在不同标签节点之间的自由放置接口，用户可以针对某张表、某个数据分区的存储位置做出自定义的选择。在新版本中，用户可以将一组节点给与标签，并为这组标签定义放置约束。例如你将所有位于纽约机房的 TiDB 存储节点定义放置策略：\n\n```\nCREATE PLACEMENT POLICY 'newyork' CONSTRAINTS = \"[+region=nyc]\";\n```\n\n然后将这个策略应用于表：\n\n```\nCREATE TABLE nyc_account (ID INT) PLACEMENT POLICY = 'newyork';\n```\n\n通过这种方式，所有 NYC_ACCOUNT 的数据将存放在纽约机房，而用户的数据访问请求也自然会被路由到本地机房。\n\n类似的，用户可以为机械磁盘节点打标签用以冷存和低频访问以节省成本，并将旧数据分区放置在低成本节点。\n\n```\nCREATE PLACEMENT POLICY storeonhdd CONSTRAINTS=\"[+disk=hdd]\";\nALTER TABLE orders PARTITION p0 PLACEMENT POLICY = 'storeonhdd'；\n```\n\n另外，该功能也可被用于多租户隔离场景。例如在同一集群中，用户可以将不同租户的数据经由放置规则分配到不同节点，而不同租户的负载也将自动由对应节点处理。这使得 TiDB 具备了租户隔离的能力，且辅以合理的权限设置，租户之间仍保有数据互访的可能。\n\n虽然是一个大型功能引入，但实际上这个框架的主体部分，已经通过 TiFlash 的行列分离能力于 4.0 版本间接发布给用户使用了，且经过了超过一年的迭代和打磨。因此，虽然是一个重大变更，但该框架却已经拥有了成熟的案例。本次发布将 Placement Rules 能力借以 SQL 的形式向用户全面开放，除了解决上述问题之外，也希望借助社区无限的想象力，发掘更多有价值的用法。\n\n### 热点场景应对\n\n分布式数据架构下，有一个恼人的话题：如何应对热点。在热点数据访问或锁冲突场景下，分布式数据库无法发挥多计算节点的性能优势，造成性能瓶颈，影响业务稳定和应用体验。TiDB 6.0 针对这类问题增加了多种解决方案。\n\n#### 小表缓存\n\n有时用户的业务同时涉及大表（例如订单）和若干小表（例如汇率表），其中大表的负载很容易通过分布式分担，但每次交易亦要访问的小表的数据却容易造成性能瓶颈。TiDB 6.0 新引入的小表缓存功能，支持显式将小的热点表缓存于内存中以大幅提高访问性能，提升吞吐，降低访问延迟，适用于高频访问低频更新的小表场景，例如配置表，汇率表等。\n\n#### 内存悲观锁\n\n通过将悲观锁事务缓存化，大幅降低悲观场景下的资源开销，CPU 和 IO 开销降低 20%左右，同时性能提升 5%-10% 左右。\n\n除了上述新增功能外，TiDB 未来还将提供基于负载的热点 region 自动分裂能力，提升热点数据的访问吞吐，解决非预期突发热点访问造成的性能问题。\n\n### 数据生态套件可管理性提升\n\n作为 TiDB 产品重要的一环，数据生态套件之于可管理性尤为重要。具体到数据迁移场景，当用户在对大规模的MySQL Sharding 系统进行迁移时，需要有很多的迁移任务、迁移规则、源端和目标端表相关的配置和管理工作。 在数据同步环境的日常管理过程中，经常需要对数据同步任务进行监控、诊断、创建、删除等管理操作。 命令行的操作在进行复杂运维操作，或者大量任务操作时，通常会效率很低，而且容易出错。由此，在新版本中，DM 推出了基于 Web 的图形管理工具，帮助用户更加方便的对整个数据迁移环境进行管理。它包含了如下功能：\n\n- Dashboard： 包含了 DM 中同步任务的主要监控信息和运行状态信息，帮助用户快速了解任务的整体运行状况，以及与延迟、性能相关的重要信息。\n- 数据迁移任务管理功能，帮助用户监控、创建、删除、配置复制任务。\n- 数据迁移上游管理功能，帮助用户管理数据迁移环境中的上游配置，包含了，新增、删除上游配置、监控上游配置对应的同步任务状态、修改上游配置等相关的管理功能。\n- 迁移任务详细信息管理功能，根据用户指定的筛选条件查看同步任务的具体配置和状态信息，包括，上下游配置信息，上下游数据库名称、表名称等。\n- 集群成员信息管理功能，帮助用户查看当前 DM 集群的配置信息和各个 worker 的状态信息。\n\n![1.png](https://img1.www.pingcap.com/prod/1_3e5c53fbc3.png)\n\n### 全新的管理平台和智能诊断套件\n\n#### TiEM 管理平台\n\n从最初版本至今，TiDB 的日常运维都是以命令行操控为主。虽然 TiDB 从 4.0 开始推出 TiUP 工具对 TiDB 集群进行安装部署和运维操作，降低了管理复杂度，然而它终究是命令行工具，学习成本较高，对相当多的企业用户而言，并不合意。除此之外，我们也经常遇到用户同时管理多个业务的多套集群，且配置和规格各不相同，任何集群变更和监控都是一个很大的挑战。一个无心的疏忽登录了错误的管理节点，应用了错误的变更，就可能带来无法挽回的损失。我们曾经遇到过仅仅因为切错命令行分页，而将生产集群当做测试集群关闭的惨况。现下诸多企业级数据库都拥有图形化管理界面，而 TiDB 6.0 中，也引入了 TiEM（TiDB Enterprise Manager）。\n\n![2.png](https://img1.www.pingcap.com/prod/2_2a7eeabc8b.png)\n\n在当前版本中，TiEM 集成了资源管理，多集群管理，参数组管理，数据的导入导出，系统监控等诸多功能。用户可以通过 TiEM 在同一界面管理多套集群，扩缩容，数据备份恢复，统一参数变更，版本升级，主备集群切换等。TiEM 还内置了监控和日志管理，让集群巡检变得轻松高效，不再需要在多套工具和监控之间不断切换。通过 TiEM 的管理平台，除了方便的统一界面进行多集群管理外，也将很大程度避免人为疏失带来的灾难，而用户也可以从繁杂易错的工作中解脱。\n\n#### PingCAP Clinic 自动诊断服务（预览版）\n\n和其他数据库系统一样，TiDB 本身存在一定的内在的复杂性，问题诊断和解决并不是非常容易的事情。而对于云环境下，服务提供商更需要面对大量不同用况的用户，对于集群的问题定位，诊断，问题解决都提出了全新的挑战。为了更好更高效地应对问题诊断，定位和修复，TiDB 必须用不同以往的方式面对。究极而言，我们希望数据库是可以智能地自调整自修复，但这却是一个非常宏大的目标。\n\n传统上，我们依赖具备专家知识的工程师 / DBA 进行分析诊断，但这些知识是否可以通过程序来提供，以方便我们的日常运维管理，甚至这些知识是否可以通过不断积累我们由不同真实案例而变得更智能更强大？作为 TiDB 迈向自服务的全新一步，我们希望对于集群运行情况的分析，风险预警和问题定位是可以作为智能服务来提供的：在 TiDB 6.0 发布的同时，新版本也引入了智能诊断服务 PingCAP Clinic 的预览版。PingCAP Clinic 从全生命周期确保集群稳定运行，预测并降低问题出现概率，快速定位并修复问题，加速问题解决效率。它集成了诊断数据采集、智能诊断、智能巡检、云诊断平台等功能，这些功能将逐步向用户开放。\n\nPingCAP Clinic 通过访问（经过用户允许）信息采集组件获取各类故障信息，在对各种问题进行排查的同时也不断增强自身的能力。PingCAP Clinic 将受益于我们面对的数千个场景迥异的用户所提供的各类集群运行数据。我们会不断将从问题中抽象出的规则固化到智能诊断中，并通过在线/离线升级的方式分发给 TiDB 用户，这使得用户在使用 TiDB 的同时也不断获得整个 TiDB 社区的积累。可以预见到的是，当 TiDB 获得更多云端客户时，PingCAP Clinic 也将更容易不断「学习」来提高自己。作为一个宏大目标的起点，我们欢迎大家的关注和讨论。关于更多 PingCAP Clinic 的信息，请阅读官方文档，并关注后续进展发布。\n\n### 面向非专家的可观测性\n\n作为可管理性的一个重要组成部分，可观测性是TiDB 一直以来都在不断加强可观测性。除了其他分布式系统都具备的基本监控和指标，从 4.0 起，TiDB 已陆续发布了诸如 Key Visualizer，SQL 统计和慢查询展示，监控关系图，持续 Profiling 等分布式数据库专有的功能，这些都是对 TiDB 的可观测性很好的补强，能帮助 DBA 和工程师更好地理解自己业务在 TiDB 上的运行情况，以更精准地定位问题和进行系统调优。但这些多多少少是专家向的特性，需要用户对系统有一定的技术理解。\n\n而从 6.0 开始，我们将引入更多的非专家向可观测性特性，让对分布式数据库和 TiDB 并不那么了解的用户也能排查系统问题。Top SQL 的推出是践行理念的第一步。\n\nTop SQL 是一个面向运维人员及应用开发者的一体化、自助的数据库性能观测和诊断功能。与现有 TiDB Dashboard 中各个面向数据库专家的诊断功能不同的是，Top SQL 完全面向非专家：你不需要观察几千张监控图表寻找相关性，也不需要理解诸如 Raft Snapshot、RocksDB、MVCC、TSO 等 TiDB 内部机制，仅需要知道常见数据库概念，如索引、锁冲突、执行计划等，即可开始使用它来快速分析数据库负载情况，并提升应用程序的性能。Top SQL 以用户自助使用、判断分析的方式，与 PingCAP Clinic 自动化规则一起，共同为用户提供从常见到复杂罕见的不同性能场景的覆盖方案。\n\nTop SQL 无需额外配置，在 TiDB 6.0 版本中开箱即用，集成于 TiDB Dashboard 图形化界面，且不影响数据库现有应用程序性能。当前版本 Top SQL 率先提供各个节点 30 天的 CPU 负载情况，你可以直观了解各节点的高 CPU 负载是来自于哪些 SQL 语句，从而快速分析诸如数据库热点、突发的负载升高等场景。在未来版本中我们还将持续迭代改进 Top SQL，重组整合流量可视化、慢查询、锁视图等现有的专家功能到 Top SQL 中，以一体化的、面向非专家的功能形式，帮助运维人员及应用开发者更简单、更全面地分析数据库性能问题。\n\n![3.png](https://img1.www.pingcap.com/prod/3_173646c19e.png)\n\n## 更成熟的 HTAP 能力\n\nTiDB 5.0 是其分析引擎架构初步成型的版本，这个版本中我们引入了 MPP 执行模式，从而得以服务于更广的用户场景。这一年来 TiDB HTAP 也经受了严苛的考验，无论是双十一场景下数十万 TPS 写入合并数十张实时报表中高频刷新，交易分析混合下优化器自动路由完成的高并发数据服务，这些用例都成为 TiDB HTAP 不断成熟的依托。相较 TiDB 5.0，最新版本中分析引擎 TiFlash 拥有了：\n\n- 更多算子和函数支持：相较 5.0，TiDB 分析引擎新增加了 110 多个常用内建函数以及若干表关联算子。这将使得更多计算能享受 TiDB 分析引擎的加速带来的数量级性能提升。\n- 更优的线程模型：在 MPP 模式下，以往 TiDB 对于线程资源是相对无节制的。这样实现的后果是，当系统需要处理较高并发的短查询时，由于过多的线程创建和销毁带来的开销，系统无法将 CPU 资源用满，从而带来大量资源浪费。另外，当进行复杂计算的时候，MPP 引擎也会占用过多线程，带来性能和稳定性的双重问题。针对这个问题，最新版中引入了全新的弹性线程池，并对算子持有线程的方式进行了较大重构，这使得 TiDB MPP 模式下的资源占用更为合理，在短查询下达到同等计算资源倍增的计算性能，且在高压力查询时稳定性更佳。\n- 更高效的列存引擎：通过调整存储引擎底层文件结构和 IO 模型，优化了访问不同节点上副本和文件区块的计划，优化了写放大以及普遍的代码效率。经客户实景验证，在极高读写混合负载下提升超过 50%～100% 以上并发能力，同等负载下大幅度降低 CPU / 内存资源使用率。\n\n## 强化的容灾能力\n\n除了可管理性之外，作为数据容灾的关键组件，TiCDC 也迎来了核心能力增强：通过对整个处理增量数据处理过程的优化、控制拉取事务日志速度等方式，TiCDC 在大规模集群数据容灾方面的能力有了长足的进步。\n\nTiCDC 对于增量数据的提取、排序、加载、投递等多个处理流程都进行了优化，降低在处理每一张表的增量数据时所需要使用的 CPU、内存量、减少进程间的通信次数。 这极大地提升了 TiCDC 在大规模集群下同步数据的稳定性、并降低了资源消耗和数据延迟。 真实用户场景测试显示， 6.0 版本的 TiCDC 可以在上游集群的规模达到 100K 张表、集群每秒钟数据改变行数低于 20 K/s、数据改变量低于 20 MB/s 的情况下，确保 99.9% 的数据延迟时间低于 10 秒钟， RTO < 5 分钟，RPO < 10 分钟。就整体而言，在上游集群 TiDB 集群节点进行计划内升级或者停机的场景中，可以将延迟控制在 1 分钟之内。\n\n另外，为了降低数据复制过程中对上游集群的性能影响，保证数据复制过程中业务无感知， TiCDC 增加了对于主集群事务日志扫描的限流功能。在绝大多数情况下，确保TiCDC 对于上游集群的 QPS、 SQL 语句平均响应时间的影响不超过 5%。\n\n## 面向企业级版本的锚定\n\n随着对版本发布的节奏把控不断成熟，随着 TiDB 6.0 发布，针对企业级用户的稳定性要求，我们也再次进行发版模型调整。从 6.0 版本开始，在 2 个月为周期内的版本迭代基础上，TiDB 发版策略将引入半年为发布周期的 LTS（Long Term Support）版本，同时为用户提供只包含修复的长期稳定版和快速迭代版以兼顾不同倾向的版本需求。其中 LTS 版本面向不需求最新功能，但希望不断收到问题修复的用户，生命周期为 2 年；而非 LTS 版本则拥有更高的迭代速度，只维护 2 个月，面向对最新功能有需求且稳定性需求不高的非生产场合。规划中的 TiDB 6.1 将作为第一个 LTS 版本发布。\n\n## 展望\n\n由于云数据库并不强调版本，因此在前文中我们没有对 [TiDB Cloud](https://tidbcloud.com/free-trial) 进行过多赘述。但是可以看到，6.0 版本不但是 TiDB 迈向企业级 HTAP 数据库的又一个全新版本，也是 TiDB 向云数据库进发的新起点。诸如可管理性主题，数据放置框架，Clinic 自动诊断兼顾了私有部署的使用，但实际上它们都将在云端形态下拥有更大的潜力。  \n\n云原生数据库是一个很有趣的话题。我们对云数据库的认识随着持续的摸索在不断提升中，从在云上可运行的数据库，到借助云基础设施实现的数据库，再到在云上可自运维数据库，6.0 版本是我们践行这个理念的重要一步。试想，结合良好的可管理性，当云数据库服务为成千上万用户提供支持的同时，也可以采集到远超于现在的非敏感的集群运行数据，这些数据将作为数据库自运维自服务的基础信息，不断学习不断进化，在用户体验提升的前提下也解放服务后端团队更多的资源，集中精力更好地提供用户所需的产品，这将带来私有部署形态无法替代的优势。  \n\n而在后续的版本规划中，我们将尝试通过借助云存储服务和资源按需启停等技术，为用户提供超越以往形态的使用体验。借助开源的力量，让用户觉得云服务相比免费使用私有部署更值得，转化为我们新的推力，是我们和整个整个社区双赢的共同目标。\n\n查看 TiDB 6.0.0 [Release Notes](https://docs.pingcap.com/zh/tidb/v6.0/release-6.0.0-dmr)，立即[下载试用](https://pingcap.com/zh/product/#SelectProduct)，开启 TiDB 6.0.0 企业级云数据库之旅。\n\n\n","date":"2022-04-07","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"tidb-6.0-release","file":null,"relatedBlogs":[]},{"id":"Blogs_364","title":"TiDB Hackathon 2021 — TPC TiKV：这可能是本届比赛中最硬核的项目 | TPC 战队访谈","tags":["TiDB Hackathon 2021"],"category":{"name":"社区动态"},"summary":"本篇文章将介绍 TiDB Hackathon 2021 TPC 战队赛前幕后的精彩故事。","body":"![三等奖 TPC.mp4](https://img1.www.pingcap.com/prod/TPC_f7e65b65e5.mp4)\n\n数据库调优可以使数据库应用运行得更快，但对于很多人来说，对数据库内核进行调优是一项很有挑战的“技术活”，是只属于少部分内核研发们的“游戏”。但即使是他们，对数据库内核进行性能调优，也充满了不确定性，它需要综合考虑各种复杂因素，如硬件层面的 CPU、 I/O、 内存和网络，以及软件层面关于操作系统、中间件、数据库参数等配置，还有运行在数据库上的各种查询和命令等。**在本次 Hackathon 2021 比赛中，TPC 战队就完成了这一项“挑战”，采用 bottom-up 的设计思路，更好地利用硬件资源，使用 TPC (thread-per-core) 线程模型优化了 TiKV 的写入性能、性能稳定性和自适应能力**。TPC 战队也凭借这一硬核项目一举斩获了三等奖与技术潜力奖。\n\n> “该项目是本届 Hackathon 中最硬核的项目，我给了非常高的分数。 TPC 在其中做了非常多的工作，我预感到后续落地的难度，他们用了 io uring，不过貌似也遇到了不少的坑，后面也可以选择 AIO 或者单独的异步线程机制。因为用了新的 raft engine（这个会在 TiDB 5.4 GA），也很方便做 parallel log write，充分利用多队列 IO 特性。这个特性在 Cloud 上面也是很关键的，因为 EBS 这些盘单线程写入 IOPS 其实真不高。另外，我看他们后面还会去掉 KV RocksDB 的 WAL，这样几个线程池就真能合并，只做计算操作，IO 操作都完全变成异步了。”\n>\n> <p align=\"right\">——评委唐刘</p>\n\nTPC 战队由来自 TiDB 分布式事务研发团队的陈奕霖与赵磊组成，其中，陈奕霖从 2019 年就参加 TiDB Hackathon ，并凭借线程池项目拿了当年的一等奖，而彼时他还是一名刚刚进入 PingCAP 的实习生。如今已毕业的他，留在 PingCAP 继续做事务相关的研发工作，已经是一名 TiDB Hackathon 老选手了。\n\n## TiDB Hackathon 的魅力\n\n**陈奕霖**：**其实对于 PingCAPer 而言， Hackathon 是一个发现更多可能性的机会**。我们平时工作中都有着很多紧迫的项目，没机会探索 TiDB 更多新的可能性，Hackathon 就给予这样的机会。在平时的工作场景中，我们经常会产生一些想法，但没机会去尝试。 在 Hackathon 中就可以将这些想法实践出来，并通过 DEMO 展示它的效果与潜力，如果实现得好，最后还有可能落地进入生产代码。\n \n## 项目灵感来源\n \n**陈奕霖**：赵磊非常渴望做这个项目，项目灵感也主要来源于他。平时在做内核开发以及解决一些用户问题时，我们发现 TiKV 的整体性能比较一般，并且有着很强的不确定性，难以调优。赵磊在研究另一款数据库产品的代码时，发现那个架构中的一些技术其实可以有效提升 TiKV 的性能。所以就想把该产品架构思路中用到的一些技术应用到 TiKV 来，看是否能提升 TiKV 的性能以及稳定性。\n\n**TPC 项目的首要目的在于性能提升**，TiKV 对于资源的利用一直不是很好，如对 CPU 或 IO 资源利用不充分，通过该架构可以通过并发写 WAL 实现对 IO 资源的充分利用。线程池方面的新架构也可以比较合理地去规划 CPU 的资源使用，特别是在云环境下，可以让 TiKV 得到更稳定、更可预期的性能。\n \n## 比赛中的异步协作\n\n**陈奕霖**：我们差不多在元旦假期才开始做初步开发工作，与平常工作时差不多，我们大部分时间还是异步化的协作，我有什么进展就直接同步给赵磊，这个过程可能会通过邮件或 Github 通知进行。开发过程主要分为两大块：**一方面是改 TiKV 本身的 raftstore** ，这是赵磊做的。**另一方面是关于 Raft engine， TiKV 用来存储 Raft 日志的一个组件，我来它的异步化以及写的并发化**。\n\n其中，Raftstore 包含两个 thread pool：\n- store pool 用于处理 raft message、append log 等，raft log 会写入 raft db；\n- apply pool 用于处理 committed log，数据会写入 kv db，目前 raft db 和 kv db 均使用 RocksDB，之后 raft db 会切换到 raft-engine。\n\n![1.jpg](https://img1.www.pingcap.com/prod/1_d34d14bc7e.jpg)\n\nRocksDB 无法很好利用现代高速硬盘，它的 foreground write (WAL) 只能提供 1 个 I/O depth 且 write group 间同步、排队的消耗很大，而 NMVe SSD 等高速硬盘需要高的 I/O depth 来打满 IOPS，或者大的 I/O size 加上不那么高的 I/O depth 来打满 bandwidth，但大的 I/O size 不适合 OLTP 系统，因为攒大 batch 通常意味着高延迟。\n\n![2.jpg](https://img1.www.pingcap.com/prod/2_87730304bd.jpg)\n\n为了优化 TiKV 的 disk 使用，raft engine 需要支持并发写 WAL 或者拆分 raft db 来并行写多个 WAL 文件，为了更公平和 upstream TiKV 做性能对比，本次 Hackathon 没有对数据模型做很大改动，会实现并行写 WAL，不会拆分 raft db。而为了最大化 disk 压力、更好的 CPU 使用率以及更好的性能稳定性，TPC 选择使用 async I/O 来实现该功能。\n\nStore pool 实现了上述功能后，它的性能应该会大幅优于 apply pool，但可能会消耗更多的资源从而影响整体的性能，如消耗了更多的 CPU 和 disk I/O 资源导致 apply pool 变慢、积攒太多 committed logs 导致 OOM 等，且整个 pipeline 的性能受限于最慢的一个阶段，需要根据最慢的阶段做 back pressure，如调整 store pool 和 apply pool 的线程数量从而保证速度匹配。但拆分多个线程池实在是不易用、不灵活，为了避免手动调优，我们将 store pool 和 apply pool 合并为单个线程池。为了实现这一目标，raft engine 使用 async I/O 也是必需的，kv db 同样需要使用 async I/O，但 kv db 理论上可以不写 WAL，因为数据可通过 raft log 回放且该功能已有方案，在 Hackathon 上会强行去掉 kv db 的 WAL。除了 async I/O 外，还需要实现 CPU scheduler 来保证当 CPU 成为瓶颈时，单个线程内不同任务成比例地使用资源，如原来 store pool 和 apply pool 的任务各使用 50% 的 CPU 资源。\n\n有了 CPU scheduler 后可以把更多的线程池合并在一起从而实现真正的 unified thread pool，如 gRPC thread pool、scheduler worker pool、unified read pool、RocksDB background threads、backup thread pool 等，CPU scheduler 会给每个原先 thread pool 的任务分配一定比例的资源，且可动态调整，从而提升资源紧张时的性能稳定性，实现自适应，避免手动调参。\n\n## 遇到的最大技术困难 \n\n**陈奕霖**：这一次我们用的各种技术都是特别激进和核心的技术，遇到了很多依赖库或者 Linux 内核的一些意外情况，编写时有一些东西并不符合预期。比如说我们用的 thread per core 库，当我们想要根据 latency 去做抢占的时候，它在绝大多数的内核上都不能工作。\n\n此外，我们在 AWS 上尝试了很多种内核。当使用 AWS Linux 默认提供的内核配合 IO uring ，遇到很多问题。后来，我们辗转到一个更新的内核上终于可以使用了。另一方面是文件系统，我们常用的有 ext4 和 xfs 两种文件系统，它们在异步写的行为有一些区别，我们也是尝试多种内核以及换不同的文件系统后，才终于找到某一种组合，基本符合我们对于异步写的行为预期。我们整体过程中遇到的最大问题，就是用的的技术太不成熟了，遇到了很多内核方面的坑，这方面其实还挺痛苦的。\n \n## 比赛过程中有什么遗憾？\n\n**陈奕霖**：比较遗憾的是时间比较紧，对整个系统的调优还没有调到比较好的程度，最后效果比我们想象中的要差一点。在整个过程中，我们花了大量的时间让这个项目跑起来，让它基本符合我们的预期。\n\n比赛中有一个有趣的事，我其实一直都不清楚队伍的宣言是什么，后来到现场才发现队旗下面的小字写的是“**冠军被我内定 or 小丑竟是我自己**”，结果在 Hackathon 的前几天，我突然发现赵磊把他的头像改成了小丑……\n\n## 本次比赛体验\n\n**陈奕霖**：之前赵磊跟我们分享其他技术架构时，还只是一个理念或者概念层面上的，实际运用到 TiDB 上会怎么样？ TiKV 的问题究竟是不是在这里？其实我们也不是很清楚。通过这次 Hackathon ，我们证明了这个想法一定程度是对的，是确实有用的，TiKV 也因此得到了改进。**我想这也是 TPC 这个项目给  TiKV 这个产品的进化验证了一条正确的路**。\n \n## 对项目未来有什么期待？\n\n**陈奕霖**：我觉得如果直接把这次在 Hackathon 上使用的技术栈应用到 TiKV 上，可能还不是特别可行。就像唐刘老师在评价中提到的，我们用  io uring 遇到了很多问题，但是其实可以转而求其次去使用 Linux AIO 之类的。同时，像 Raft engine 这个东西，它的异步化未来也是可以推进的。这个项目比较大的作用就是指明了 TiKV 可能的演进方向。\n\n> 延展阅读：点击查看更多 [TiDB Hackathon 2021 优秀项目分享](https://pingcap.com/zh/blog/?tag=TiDB%20Hackathon%202021)\n","date":"2022-03-15","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"tpc-tikv","file":null,"relatedBlogs":[]},{"id":"Blogs_359","title":"TiDB Hackathon 2021 — TiDB 可观测性方案落地探索 | “我们这么菜评委不会生气吧”团队访谈","tags":["TiDB Hackathon 2021"],"category":{"name":"社区动态"},"summary":"本篇文章将介绍 TiDB Hackathon 2021 “我们这么菜评委不会生气吧”团队赛前幕后的精彩故事。","body":"![三等奖 我们这么菜评委不会生气吧.mp4](https://img1.www.pingcap.com/prod/_5ba4ef1753.mp4)\n\n在 TiDB Hackathon 2021 赛事中，没有错过任何一届赛事的元老级选手王鹏翰再次得奖，也是继滑滑蛋之后，又一支男女朋友并肩参赛的队伍。\n\n王鹏翰目前工作于思科旗下做应用性能管理的公司 AppDynamics，主要从事日志搜索引擎的研发和可观测性相关的一些工作。陈思雨是 PingCAP Chaos Mesh 团队的研发。\n\n这次的参赛项目 Collie Diagnosing Platform，是一个集故障场景信息收集、UI 在线观察分析、机器学习辅助诊断于一身的故障诊断分析解决平台。结合了两人在工作中的实际场景，探索了未来 3-5 年 DBA 和运维人员的工作方式，评委们给予了非常高的评价和期待，拿下了本届 Hackathon 的三等奖。\n\n> 项目意义重大，让 DBA 在分析问题时，面对那么多 Metrics，不再那么头大。\n>\n> <p align=\"right\">——多点 Dmall 数据库团队负责人冯光普点评</p>\n\n\n> 数据库自治是领域的重要方向，参赛团队在理论和工程实践方面都做的比较好，后续可以进一步对标阿里云的 DAS 产品进行改进完善，将弥补这一领域项目在开源方面的空白。\n>\n> <p align=\"right\">——美团数据库研发中心负责人李凯点评</p>\n\n\n\n\n## **关于团队**\n\n**Q：这个队名的由来有什么故事？** \n\n**陈思雨：** 队名来自于 Dota 的一个语音包，在游戏里如果队友做什么比较蠢的操作的时候，播放下这条语音就达到效果了。\n\n可以通过这条视频体会一下：https://www.bilibili.com/video/BV1N34y1m7wa\n\n**Q：两位都是 Hackathon 的老选手了，Hackathon 对你们的吸引力是什么呢？** \n\n**王鹏翰：** 对我来说 Hackathon 就是进行一个 deadline 的设置，逼着你在很短时间内学大量的东西。本来我很早就想去学习一下如何用机器学习做一些根因性分析相关的东西。但是已经想了一年，实际上只看了一点点。在 Hackathon 中，就可以在很短的时间内了解它并且把它使用起来。有一个 deadline 就会逼迫你快速去学习，这个时候学习效率非常高，睡觉的时候满脑子都在想着这个地方还能怎么优化一下，那个地方还怎么搞。当然，顺便还能拿到一点奖金。\n\n**陈思雨：** 跟他差不多。另外，在 Hackathon 里还能看到很多不一样的 idea。\n\n\n\n## **项目灵感** \n\n**Q：你们最初为什么会想到要做这样一个项目的？能分享下你们的灵感是什么吗？** \n \n**王鹏翰：** 我们前两年参赛基本上都是在做 FDW，就是给 TiDB 接一个通用的外部数据源，今年的一等奖项目从某种意义上来说也是外部数据源的一种。感觉已经做得有点心神憔悴了，那些 Hard Code 的功能对于我们这种老年人来说，无论是脑力还是体力都已经跟不上了，今年就只能在搞花活的方向去另辟蹊径。\n\n我找项目灵感的一个核心点是去发掘身边真实遇到的一些情况，试图抽取出一个通用性的问题，然后去想如何通过工具或者方法论把它高效地解决掉。包括去年的 idea 如何写出一份优雅的文档，今年的 idea 如何快速地发现故障和诊断故障，都跟工作是息息相关的。\n\n我现在的工作是在可观测性领域，这个领域目前跟机器学习相结合的东西大多都还在论文阶段，但在实际环境中如何把它更好地落地，还是比较少有人去尝试的，刚好 TiDB 已经把整个基础做得非常好了，就想借 Hackathon 的机会来做一些尝试。\n\n**Q：在这次比赛过程中，你们的队伍成员之间是如何分工的？** \n\n**王鹏翰：** 思雨负责如何用 TiDB 去模拟故障的发生，刚好也用了他们团队的产品 Chaos Mesh。然后我使用一些工具来代替人脑，观察这个时间段是否发生了问题，用机器学习的方法代替人做一些简单的判断。就等于说运维人员有一个很大的屏幕，上面有几十个图，每个图里都有很多的折线。一般情况下，如果一个系统在平稳运行的话，这条线基本是平的，但出现故障的时候，会有很大的波动。\n\n![1.jpg](https://img1.www.pingcap.com/prod/1_259e788893.jpg)\n\n现在都是 DBA 用人眼去观察，故障的判断也是基于人的经验和思考模式。但现在 TiDB 中像这样的指标就已经有几千个了，未来还会有更多。这就意味着靠人去观察这些东西会变得越来越复杂，越来越慢。我们可以用机器去帮你快速地筛选出来，比如 1000 张图中有 10 张图有这种故障，然后你再去观察这 10 张图就可以，帮你节省了大量的时间。\n\n在理想的环境下，准确率能达到 70-80%。但如果在现实环境中，你可能认为有些并不是故障，所以这个指标会有一些波动，噪声会很大。\n\n\n\n## **技术困难&应对** \n\n**Q：在比赛过程中你们遇到过什么比较大的技术困难？** \n\n**王鹏翰：** 主要是数据集质量问题。目前在 AI 领域，算法可能不是最关键的，最关键的是数据集。如果你的数据集够好，通过相应的算法都能得到一个很好的答案。但如果你的数据集比较糟糕，那你得出来的答案永远是错误的。所以我们花了很多时间在数据集模拟这一块。\n\n另一块就是在思考如果换我来运维系统，从 DBA 的角度来看问题的时候，我该如何合理设计用更高效合理的方式来做这个事情。其实不管是 TiDB 也好，还是一套系统也好，都有一套共用的方法论，可以通过观察资源，比如 CPU 资源或内存资源，或者观察事务（一个http请求，一个数据库查询请求）。从而知道系统是否按照预期在运行。如果没有按照预期运行的时候，我们的应用能给一个告警，还能告诉你是什么原因导致系统没有按预期运行。\n\n这就是所谓的根因分析（Root Cause Analysis），我们希望通过机器学习，告诉你发生故障的原因是 CPU 不够，还是机器上有另外的任务抢了 CPU 资源，那你就应该去加更多的 CPU 资源。\n\n**陈思雨：** 其实其这个问题不应该仅仅是 DBA 或者运维关心的，因为他们（王鹏翰所在的 APPDynamic）是全员 Oncall 的，所以他会思考遇到一个 Oncall 的问题应该怎么去解决，应该怎么去优化这个 Oncall 的流程。我们这次做的项目也是在优化这个 Oncall 的整体流程。\n\nDBA 可能会更专业一点，我们这次做的产品是面向那些非 DBA 人员，因为 DBA 看 Grafana 这种比较专业的指标就会有很明确的一个判断。但是如果是刚上手的人，比如说刚开始学习 TiDB，也可以通过我们的产品有个初步的方向判断，这个故障原因是一个网络延迟还是怎样。\n\n**王鹏翰：** 遇到的另一个问题就是现有的机器学习也好，深度学习也好，离所谓的 AIOps 还有非常远的路要走，而且有很大的难度。为了这次的项目能有一个成品出来，主要依赖了两篇论文，一篇是 SIGMOD 2016 的《DBSherlock: A Performance Diagnostic Tool for Transactional Databases》，另外一篇是 VLDB 2020 的《Diagnosing Root Causes of Intermittent Slow Queries in Cloud Databases》。\n\n这 2 篇论文做得非常好的一点就是把场景局限起来了，针对一个小的领域、小的场景能做到高度的准确性，比如一个运维可能 10% 的工作是在处理这类问题，那这个项目能自动化地解决这 10% 的工作量。然后像拼积木一样，今天把这个问题的积木拼装好，下次把另外一个问题拼装好，慢慢就把整个全自动化的事情给拼接出来了。\n\n\n\n## **未完成的遗憾 & 期待**\n\n**Q：这次 Hackathon 的时间有限，你们在比赛过程中有什么遗憾？** \n\n**王鹏翰：** 体验满意，完成个人的既定目标，在短时间快速学习了机器学习，并做了个小产品。aiops 可以在一些特定的领域降低人的工作负载，但离最终广泛的替代运维还有非常远的路。\n\n**陈思雨：** 8 分钟的演示时间太短了，我们一直在缩减 PPT，调整我们要突出哪些重点，还要保证在这么短的时间内让这么多位评委老师都 get 到。\n\n**Q：你们的项目这次获得了三等奖，对这个项目未来有什么展望与期待？** \n\n**王鹏翰：** 首先，这个项目的实现方法还非常雏形，有很多的细节还需要跟大家探讨和交流才能摸索出来。而且我们也没有希望把这个项目做成一个产品，更多的是方向上的探索，探索未来 3-5 年运维或 DBA 的工作方式。\n\n随着技术的突飞猛进，运维的难度也越来越大。运维的管理对象从原来的单台机器变成了云和 Kubernetes，节点越来越多，涌现出来的信息也越来越多。从开发的角度来说，会把更多的信息暴露出来，统一地进行管理和追踪。但如何更好地利用这些信息？这个领域在国内还是鲜有人去思考的，也就是所谓的可观测性（Observability）。\n\n国外很多公司，包括我们公司（AppDynamic）都是这个领域的主要参与者，在非常活跃地往这个方向进行一些探索。PingCAP 已经算是做得很不错的了，把整个数据库的可观测性做得很好。希望国内有更多的公司和个人能去思考一下，如何运用现有的工具，让你的系统有更好的可观测性，从而降低运维压力和成本。  \n\n> 延展阅读：点击查看更多 [TiDB Hackathon 2021 优秀项目分享](https://pingcap.com/zh/blog/?tag=TiDB%20Hackathon%202021)","date":"2022-03-10","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"exploration-of-tidb-observability-plan","file":null,"relatedBlogs":[]},{"id":"Blogs_356","title":"TiDB Hackathon 2021 — MVCC 时光机：在 TiDB 的时空自由穿梭丨渡渡鸟复兴会赛队访谈","tags":["TiDB Hackathon 2021"],"category":{"name":"社区动态"},"summary":"本篇文章将介绍 TiDB Hackathon 2021 渡渡鸟复兴会团队赛前幕后的精彩故事。","body":"> TiDB 处理各种灾难故障可谓轻车熟路，但是常言道“天灾易躲，人祸难防”，对于各种误操作、bug 写入错误数据、甚至删库跑路，目前还没什么招。我们项目最初也是为了处理这些“意料之外”的事故。项目最初的名字叫 TiDB Flashback，后来又觉得这个名字过于贫瘠，无法体现项目内容的优越性，后来索性改成了“MVCC 时光机”。\n>\n> <p align=\"right\">——渡渡鸟复兴会战队</p>\n\n![三等奖 渡渡鸟复兴会.mp4](https://img1.www.pingcap.com/prod/_eb5b5a4829.mp4)\n\n在 TiDB Hackathon 2021 赛事中，渡渡鸟复兴会赛队的作品“MVCC 时光机”充分利用 MVCC 特性，加强 MVCC 数据的查询、整理、恢复的能力，提高问题处理的效率，摘得了赛事的 “三等奖” 。\n\n> 一个非常 smart 和轻量级的实现，效果很不错，期待尽快发布上线。\n>\n> <p align=\"right\">——评委冯光普</p>\n>\n> 这个项目是给运维同学在某些时候救命的功能。它通过 SQL 很好地解决了运维的操作问题。更赞的是，该项目引入了多 Safepoint 机制，也就是可以给 TiDB 集群定期做一些全局 Snapshot，进行快速轻量级的逻辑备份。\n>\n> <p align=\"right\">——评委唐刘</p>\n\n## 关于项目\n\n### 天灾易躲，人祸难防\n\n作为一款分布式数据库，完善的高可用和容灾机制可以说是 TiDB 的核心特性。然而在生产中，理论上的灾难恢复和实际上要面对的却可能大相径庭。不可预知的硬件故障、自然灾害导致的断网断电固然可怕，而把生产环境当成测试环境的误操作、有漏洞被黑客攻击、业务出 Bug 写坏数据反而可能是更高频的事故。\n\n队员之一 @disking 曾经就职于游戏公司，对这种“人为的失误”感受颇深：业务同事写的代码中出了一个 bug，在版本上线后的几个小时内被别有用心玩家利用获得了许多不正当的收益，这时候就要进行回档操作，让游戏数据回到某个具体的时间点，需要实现的就是类似“时光机”的功能。手动回档、数据丢失造成的损失都会给团队带来很大的麻烦。\n\n现在物理上的故障处理 TiDB 已经给出了像 BR 工具、两地多中心方案等解决措施，而一句`rm -rf /*`，或者“实习生误操作”导致的错误数据写入带来的风险却更加不可控，这也是 TiDB 缺失的一大块拼图。\n\n### Make MVCC Great Again！\n\n因为 TiDB 的事务是基于 MVCC 的，所以一段时间内的旧版本都在，理论上对于上述人祸，都是可以进行手动恢复的。但是现有的功能和计划中的功能相对较弱：\n\n- 很可能需要排查数据损坏的情况，目前只能指定 ts 去读一个时间点的数据，要查看某条记录的变化历史太麻烦\n- RECOVER TABLE 只能恢复 DROP/TRUNCATE 这种 DDL 操作，对 DML 没招\n- GC Safepoint 之前的数据恢复不了，如果想保留长时间的数据，又太费空间了\n- 恢复数据要先把数据 dump 出来再重新写入，太慢了\n\n因此充分利用 MVCC 特性，加强 MVCC 数据的查询、整理、恢复的能力，就能提高问题处理的效率。MVCC 不只是可以用来暂时性地处理事务隔离，也完全可以做为冷备，相比于外部的备份，其优点是可以更省空间，恢复数据也更方便更快。\n\n@disking 其实最早在第二届 Hackathon 时就有了这个想法，灵感来源于 Oracle 的 Flashback 功能。当时他就把这个想法放到了研发的讨论群里面却没有得到回应，而当时的他还没有足够的精力来组建自己的战队。虽然不至于说耿耿于怀，但是这么有趣、有用的想法当然要找个机会实现一下，这次的 Hackathon 就是一个实现想法的好机会。\n\n渡渡鸟复兴会就这样开始组建了。\n\n![1.jpg](https://img1.www.pingcap.com/prod/1_9b539930e5.jpg)\n\n<center>团队用20个渡渡鸟的对话情况来进行 demo</center>\n\n## 关于比赛\n\n### 如何制造一个时光机？\n\n> 谁掌握了过去，谁就掌握了未来；谁掌握了现在，谁就掌握过去。\n>\n> <p align=\"right\">——乔治·奥威尔《1984》</p>\n\n总的来说就是围绕 TiDB 的 MVCC 机制做了一些（乍）看起来比较 fancy 的操作，比如查询表记录的 MVCC 历史、篡改 MVCC 记录以及根据 MVCC 记录做到瞬时版本回退（Flashback 操作）等。\n\n整个项目比较核心，或者说比较实用的点还是 GC SavePoint 和 Flashback 功能的组合拳，通过设置定期的快照备份，利用 TiDB MVCC 的机制做到 TiDB 存储内部的“冷备“，在一些关键时刻还是有救命效果的，毕竟只需要一条 SQL 就可以达成整表数据的 Flashback。\n\n整个项目分为了三个相对独立的模块：\n\n1.MVCC Query in SQL -> 操纵过去\n\n- 参考 ` _tidb_rowid` 的实现，增加 `_tidb_mvcc_ts` ，` _tidb_mvcc_op` 虚拟列。\n- 当查询虚拟列时，TiDB 发送给 TiKV 的请求中要带上标记，指明要查询 MVCC 虚拟列。\n- 修改 TiKV 的 MVCC 读取逻辑，当需要查询虚拟列时，需要扫描所有版本，而不是只扫描最新版本。然后设置每条数据对应的虚拟列值。 `_tidb_mvcc_ts` 为事务的 `commit_ts`，`_tidb_mvcc_op` 为事务的操作类型，可以是 `PUT` 或 `DELETE`。\n\n![2.jpg](https://img1.www.pingcap.com/prod/2_0b874742dd.jpg)\n\n下面是一次演示，可以看到我们可以能用各种姿势来查询 MVCC 记录！\n\n![3.jpg](https://img1.www.pingcap.com/prod/3_35303ca236.jpg)\n\n甚至还可以去篡改某一次的 MVCC 记录。\n\n![4.jpg](https://img1.www.pingcap.com/prod/4_4eef938c3a.jpg)\n\n2.GC Savepoint -> 掌控现在\n\n- 添加 `gc_savepoint` 系统表，可以通过 SQL 增删改查来进行管理。\n- GC 进行时，需要将 `gc_savepoint` 表的数据，与原本的 `gc_safepoint` 一同存放到 PD。\n- 修改 GC 逻辑，回收数据时考虑 `gc_savepoint`。因为 GC 有传统 GC 和 compaction GC 两种，时间关系可以只做一种。\n  在设置 `gc_save_point_interval = ‘5m’` 后，在 `gc_safe_point` 之前，本来会被回收 MVCC 记录每 5 分钟保留一个版本。\n\n![5.jpg](https://img1.www.pingcap.com/prod/5_1377735a1b.jpg)\n\n3.Subsecond Flashback -> 着眼未来\n\n- 添加 `flashback table ts` SQL 语句，用于指定 table 进行数据还原。意义是将表还原至不超过 ts 时间戳指定的版本。\n- 将时间范围写入 table schema 并触发 DDL 操作，DDL 同步完成即可返回操作成功。\n- TiDB 请求 TiKV 时，需要将要忽略的 ts 区间放在请求中发给 TiKV。\n- 修改 MVCC 读取逻辑，要根据指定的区间跳过对应的版本。\n- 当 ts 区间超出了 GC 范围后，需要被清理。\n- 结合上面的 MVCC 查询，我们可以看到现在表数据中的“变化渡渡鸟”记录在某个时间节点前还是“时间渡渡鸟”，通过 Flashback 操作，我们成功让数据变回了曾经的模样，把“时间渡渡鸟”召唤了回来。\n\n![6.jpg](https://img1.www.pingcap.com/prod/6_1ae89e562e.jpg)\n\n在实际的灾难恢复场景中，如果我们一不小心错误地修改了某个表的几条数据，甚至是误删了整个表，都可以通过 Flashback SQL 来将其一键恢复到任意 MVCC 记录版本。 \n\n### 未来展望\n\n目前的实现仅基于 TableScan 进行了 Demo，还有一些 IndexScan 和点查询的适配工作没有进行；有些 TiDB 的生态工具是越过 SQL 层进行数据查询的，这方面的兼容性也是接下来需要考虑的问题。\n\n除此之外，如果能够扩展 Flashback 操作和 MVCC Query 的组合拳，就能够实现更多的功能，比如查看 Flashback 记录、撤销 Flashback 操作、修改 Flashback 记录等等。\n\n\n\n## 关于队员\n\n### 怎么来到 TiDB 的世界的？\n\n@JmPotato 刚刚结束了自己的学生生涯，现在是一名 PingCAP 的研发工程师，@RinChanNOW 是他的本科室友，也加入到了本次的项目之中。他们的另一位室友也在字节跳动分布式系统研发的部门实习。\n\n——一个宿舍的基础软件工程师！\n\n对于很多学生来说，成为一名应用开发者或者算法工程师或者进入 AI 行业都是更加主流的选择，为什么这么“巧”，他们不约而同地加入这个行业？\n\n@JmPotato 表示，是他开了这个“头”。2019 年年底，他在听播客的时候偶然听到了东旭关于分布式数据库的分享，那个时候也不知道 PingCAP。后来进行相关的学习，在学习 Raft 的过程中接触到了 TiKV、TiDB 这些项目，才慢慢了解到原来它们都是 PingCAP 的产品。那时候 PingCAP 刚好在招聘实习生，自己也觉得心驰神往，做了很多相关的准备就开始面试、进入公司实习直到现在正式加入。\n\n@RinChanNOW 也表示，是 @JmPotato 的这份实习为整个宿舍都打开了一个全新的世界，还记得当时大家一起实现一个简单的 Raft 协议，从那个时候就能感受到分布式系统的奇妙，不是被动的内卷，而是一种发自内心的热爱和向往。\n\n### 不懂 TiDB，怎么快速加入 Hackathon 并且开始工作的？\n\n虽然 @RinChanNOW 之前学习过分布式系统的相关知识，但是本身在学习和工作中都没有实际接触 TiDB 的经验。作为一名外部开发者，如何加入到这场关于 TiDB 的 Hackathon 中？这也是很多同学对于 Hackathon 活动望而却步的重要原因。@RinChanNOW 就完全没有这样的担心。一方面 TiDB 的文档丰富，体系化的学习起来并不费力；另一方面 TiDB 的社区非常活跃，无论是 AskTUG 还是 TiDB internals 或者说就是 GitHub 上，都能遇到很多志同道合的伙伴，他们也都愿意帮助 new TiDBer 快速融入社区。\n\n@RinChanNOW 也与大家分享了一些具体的学习经验：\n\n> 除了 TiDB 与 TiKV 的开发环境准备之外，需要做的一个准备工作就是了解 TiDB 和 TiKV 的代码结构与它们的数据流，也就是要去大致了解它们的源码，而这也是最耗时间的一个过程，所以我的代码量并不大，但是却花了很长时间才写完。\n> 我根据需要改动的部分，结合 PingCAP 的官方博客，对源码进行了一波学习：\n-  Select 流程：\n\n   -  [TiDB 源码阅读系列文章（三）SQL 的一生](https://pingcap.com/zh/blog/tidb-source-code-reading-3)\n\n   -  [TiDB 源码阅读系列文章（六）Select 语句概览](https://pingcap.com/zh/blog/tidb-source-code-reading-6)\n\n-  如何将查询下推到 TiKV 并执行：\n\n   -  [TiKV 源码解析系列文章（十四）Coprocessor 概览](https://pingcap.com/zh/blog/tikv-source-code-reading-14)\n\n   -  [TiKV 源码解析系列文章（十六）TiKV Coprocessor Executor 源码解析](https://pingcap.com/zh/blog/tikv-source-code-reading-16)\n\n-  Insert 流程：\n\n   -  [TiDB 源码阅读系列文章（四）Insert 语句概览](https://pingcap.com/zh/blog/tidb-source-code-reading-4)\n\n   -  [TiDB 源码阅读系列文章（十六）INSERT 语句详解](https://pingcap.com/zh/blog/tidb-source-code-reading-16)\n\n-  一条 SQL 语句的具体执行流程：\n\n   -  [TiDB 源码阅读系列文章（二十三）Prepare/Execute 请求处理](https://pingcap.com/zh/blog/tidb-source-code-reading-23)\n\n-  TiKV MVCC 读写流程：\n\n   -  [TiKV 源码解析系列文章（十三）MVCC 数据读取](https://pingcap.com/zh/blog/tikv-source-code-reading-13)\n\n### 玩真的：TiDB Hackathon 有什么不同？\n\n队伍中的 @disking 可以算是 Hackathon 的老玩家了，除了这次的 TiDB Hackathon，@JmPotato 和 @RinChanNOW 也都程度或深或浅地参与到了其他类似的编程竞赛中，谈及不同赛事体验的差异，他们有着统一的看法：很多编程竞赛更多是面向学生的，留一些有着明确目标甚至是标准答案的作业，更像一场检验编程能力的考试，比拼的可能是谁的实现更优雅，效果更佳。而参与 TiDB Hackathon 就是一种完全不同的体验。 TiDB Hackathon 更偏向实操，没有明确的选题，是一场未知的冒险，比起代码实现更重要的是创造力和思考，只有真正在用、真正参与到产品迭代中的开发者才能感受到其中的乐趣。\n\n但是受到疫情的影响，近两年的 TiDB Hackathon 虽然热闹，但还是少了一点气氛。如果有机会，还是期待明年的 Hackathon 能够和各位选手来到同一空间现场交流，来一场真正的 48 小时密集开发。\n\n> 延展阅读：点击查看更多 [TiDB Hackathon 2021 优秀项目分享](https://pingcap.com/zh/blog/?tag=TiDB%20Hackathon%202021)","date":"2022-03-04","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"mvcc-time-machine","file":null,"relatedBlogs":[]},{"id":"Blogs_350","title":"TiDB Hackathon 2021 — pCloud : 做数据库上的 iCloud丨pCloud 团队访谈","tags":["TiDB Hackathon 2021"],"category":{"name":"社区动态"},"summary":"本篇文章将介绍 TiDB Hackathon 2021 pCloud 团队赛前幕后的精彩故事。","body":"![二等奖 pCloud.mp4](https://img1.www.pingcap.com/prod/p_Cloud_94f7113cd3.mp4)\n\n曾几何时，人们在换手机时如何将数据备份/恢复还是一个令人头疼的问题。iCloud 的出现将 iPhone 的备份管理解决得无比漂亮，而且非常深入人心，现在 iPhone 用户换手机已经是一件没什么压力的事情。  \n\n而对于每一个数据库用户而言，数据库备份/恢复也是一项刚需，虽然备份管理经常被人忽视，但是一出事就是大事，对于企业来说没有数据就没有一切，**数据备份恢复是防范灾难于未然的强力手段**。据统计，企业中约有 11% 的成本和精力分配在了数据备份管理上。\n\n![01.png](https://img1.www.pingcap.com/prod/01_af1662dd63.png)\n\n目前，TiDB 用户可以使用 BR 做全量备份，并持续做增量备份，利用这些备份就可以恢复数据，但是它只能恢复到做备份的几个时间点，粒度还不够精细。而使用 TiCDC 或者 binlog 虽然可以精细地记录增量的事件，恢复数据到全量备份之后的任意时间点，但 BR 本身还没有原生支持 PiTR （point-in-time recovery）。即使实现了该功能，现在业界的解决方案也面临着复杂、易碎、高成本等问题，那 DBA 做数据恢复能不能像换 iPhone 那样简单呢？\n\npCloud 团队在本届 TiDB Hackathon 中开发了 pCloud 项目——一个全面托管在云端的 SaaS 服务，可以一站式托管数据库的备份/恢复，支持 Time Travel （恢复到任意时间点），并且底层基于 S3 存储，存储成本极低。pCloud 团队凭借这一项目一举获得了“二等奖”和“云启资本特别赞助最佳市场潜力奖”。\n\n![winner-pCloud.jpeg](https://img1.www.pingcap.com/prod/winner_p_Cloud_dc5b959e7f.jpeg)\n\n> pCloud 是一个非常有意思的项目，东旭同学直接上场带货，先抛开他个人现场极大的感染力，从实际来看，pCloud 真的做得很不错。虽然现场东旭只是展示了产品效果，聊了聊商业模式，但我知道这个项目的底层实现还是很有挑战。这也给了下一届 TiDB Hackathon 参赛同学另一种参考：一个项目，大家有时候更容易关注技术本身，但如果我们是做一个产品或一个 SaaS 服务，对于用户的理解和商业的理解也非常关键。所以，即使大家觉得自己对 TiDB 没太多理解，写不了太 hardcore 的程序，也可以从另外的方向来突破。\n> <p align=\"right\">——评委唐刘</p>\n\n## 团队：pCloud 是如何组成的？\n\npCloud 的团队由 4 位选手组成，其中包括第一次以选手身份参赛的我司 CTO 黄东旭。在往届比赛中他都是评委，但一直心里痒痒想当次选手，想到 Hackathon 比赛项目一届比一届硬核，今年如果再不赶紧上车，以后估计更没戏了。这次他在战队里的主要角色是贡献项目 idea ，画产品原型图，并作为产品经理指导团队开发。\n\n**黄东旭**：决定参赛的时候，我先去找了龙恒（ TiMatch 队长），问他我有一个很牛的 idea 你要不要干一下？他说自己已经决定做 TiMatch 了，但还是帮我找来了栾成、王浩和峻岑三位队员。\n\n**栾成**：当时东旭找我的时候跟我描述了一下他的想法，说需要一个前端工程师，我就想到了之前知乎同事里有一位前端大佬王浩，人在新加坡，当时他们那边应该是圣诞节，正好有时间就同意加入进来，在 pCloud 里主要负责前端网站的搭建。峻岑和我一直都在 PingCAP 做备份恢复，这次的主要工作就是把现有的工具（如 BR 等）接到 pCloud 上，做一些适配工作。\n\n**黄东旭**：虽然我是第一次参加，但是作为资深评委，我知道项目的完成度其实还是挺重要的，所以找到了一个好的前端等于已经成功了一半。\n\n![03.png](https://img1.www.pingcap.com/prod/03_ed953cf4d5.png)\n（ 东旭：我专门请设计师设计了一个产品 logo，一个好的 logo 等于成功的一半~）\n\n## 起源：一次商业模式的头脑风暴\n\n**黄东旭**：大概在 2020 年初，我们有一次关于 TiDB 可规模化商业模式的头脑风暴。一般来说，数据库的商业模式基本都是卖个服务什么的，但我隐隐约约觉得 open source 是一个很像 ToC 的东西，有没有可能用一些 ToC 的思路去看看 TiDB 的商业化呢？  \n\n过去做商业数据库的商业模式基本上就是收服务费，被保护的场景越重要，能收的服务费就越多。但是这个思路在“开源+云”时代发生了重大的变化：第一，Cloud 会变成一个特别普及的东西；第二，开源数据库超过了闭源数据库，它的成熟度已经基本上能够满足大多数核心的业务场景需求，开源数据库用户变成了一个非常庞大的群体；第三，Cloud 有一个好处，它把交付实现了标准化，并且付费的门槛降低了。当年 ToC 端出现了微信、支付宝等快速支付渠道，将支付门槛变得特别低，才有了爱奇艺这些订阅模式。  \n\n所以，基于这三个前提，你就会找到一个新思路：找到用户旅程中的通用路径，先不管核心不核心，极致优化用户（开发者）体验，然后利用云的基础设施把成本做低，最后利用流量入口 + PLG 走病毒式传播的路线。pCloud 这个项目的关键在于——第一，企业级用户能不能找到一个低门槛的支付渠道， 比如 SaaS；第二，这个模式一定要特别轻，不能特别贵，必须得找到一个非常自动化的切入点。因为一旦涉及到人工提供服务，这个事情就废了；第三，这个东西的用户群体要足够广， Database 本身是一个使用群体特别广的东西，而在 Database 里其实有一些东西的使用群体也特别广，那就是备份恢复。  \n\n在 ToC 领域里，关于消费者有一个冲动消费的心理学，这需要有几个前提：第一，你马上就能理解这个东西是什么；第二，好像我一定需要；第三就是这东西得特便宜。这些都具备了，消费者就可能产生冲动消费的心理。所以，我们借用了 iCloud 换手机的概念，给大家制造一个错觉，这个东西我一定需要。因为大家都需要 iCloud ，我们就把这个概念平移到 DBA 领域。如果你是一个普通消费者，其实很容易就被这样的概念吸引并付费。\n\n## 挑战：看起来不硬核，但工程度复杂\n\n![04.png](https://img1.www.pingcap.com/prod/04_bb6e65ef20.png)\n\n**栾成**：整体来说，我觉得最困难的是要把这些资源整合在一起，并且屏蔽掉很多技术细节，给用户呈现出的是一个更简化、更易用的界面。在此之前，备份 PiTR 、 TiUP 以及 SaaS 服务都是一些很零散的东西，但在这次效果展示中，我们要把它们整合在一起，这其实是要花一些功夫的。例如将 TiUP 集成到 PiTR ，实际上背后是起了很多个组件去运行备份的，然后再把增量的数据写到 S3。\n\n**陈昱**：我自己聊过一个类似的项目，他们的软件真要用起来的话，在做实施时要投入大量的人力物力。而最好的商业模型应该是所有东西都让客户 self service ，客户能够自己解决绝大多数问题。这样的话整个东西才容易 scalable ，但现在市场上很多产品都做的太复杂了，以至于实施团队可能比工程团队还多。  \n\n很多人觉得，这个项目最大的硬伤就是看起来没有那么硬核，单从技术、社区的分数上来说，我并没有给这个项目打特别高的分数。但最后就因为这个产品的理念——「简洁易用」打动了我，所以给了一个特别奖项。这让我想到 snowflake 和 Databricks 打口水仗， Databricks 说的永远都是性能， snowflake 则强调产品的易用性。\n\n**黄东旭**：老实说我觉得很多团队或者项目在尝试什么都做，想满足客户五花八门的需求，设计的产品就特别复杂。但我在这个项目里就想尝试一个理念——我非常清楚我的客户是谁，我会清晰地画出一个边界，如果超出了这个边界的复杂度，就不是我的客户。边界里的这些客户，会以一个非常顺畅的用户旅程以及非常低廉的价格去使用这个产品。简而言之，是我的客户他就会用得很爽。我相信这样的客户如果能够把量做起来，也会是一个好的商业模式。\n\n## pCloud 项目的亮点是什么？\n\n**黄东旭**：再来说这个项目里其实有几个比较硬核的点：首先，企业的备份肯定不是全量备份，而是增量备份。增量备份就要面临一些问题，比如说要回退到任意一个时间点，同时在这个时间点上不能破坏事物的隔离性，我们通过精心设计的 PiTR 技术（全量+增量），可以以很低的成本保存全量备份，支持恢复到任意时刻的数据；第二是高可用，我们要假设它跟外网的连接一直是通的，如果网络不通，那你在本地的缓存该怎么处理。如果这个网络是联通的，你可以直接在 SaaS 服务上实时看到数据中心里这些集群的状态。第三，满足全球安全合规，数据支持非对称加密存储。个人用户其实不太关心信息安全，但是企业用户一定会需要这个功能，这也可以作为这个产品商业化的服务之一。  \n\n总的来说，这个项目比起改数据库内核来说虽然不是那么硬核，但是我们用了非常多时髦的技术，它其实是一个工程复杂度很高的产品。在组队的时候，我甚至还想找一个财务同学帮我设计一个更合理的计费模型，但后来觉得这有点太复杂了，最后只用了一个比较简单的技术。但如果这个产品要继续深挖下去的话，计费其实也是一个挺复杂的模块。\n\n## pCloud 项目的假想客户是谁？\n\n评委陈昱认为 Hackathon 中绝大多数队伍的风格更像工程师范，技术讲得比较多，但产品设计理念相对来说就少很多，相较而下，东旭对 pCloud 项目的介绍风格在整个 Hackathon 中就显得特别不一样，甚至在比赛中已经想好了整个项目未来的商业化模式，这令作为投资人的他好感大增。\n\n![05.png](https://img1.www.pingcap.com/prod/05_c3609d2ab7.png)\n\n**黄东旭**：国内有一些中小型创业公司，他们可能觉得云端的 RDS 太贵，就自己买了虚拟机，在上面部署 TiDB 或 MySQL ，跑了一些企业级应用。因为预算控制，他们一般不会请专职的 DBA ，又不希望工程师的时间花在这些东西上，那他们可能就是这个产品的目标客户了。在我设想的第一阶段商业模式中， pCloud 本身会成为一个“上云的桥梁”。数据的备份使用 S3 存储在云端，特别漂亮的是 S3 是一个云中立的标准协议，每一个云都会有 S3 协议的对象存储服务，所以第二个阶段的商业模式需要走向：渠道的商业模式，这个阶段需要做两件事情：  \n\n1. 开源（不是 Open Source，而是开源节流那个开源），支持更多的数据库作为 PiTR 的数据源（把服务扩展到 MySQL PG Oracle 之类的）；\n2. 提供一键恢复到云数据库的能力（例如 TiDB Cloud，Aurora，RDS，Snowflake）。\n\n渠道的商业模式是引流，这个阶段必然是各个云数据库厂商争夺用户的阶段，pCloud 如果运作得好，就是一个天然的流量池，玩法很多。一个很好的例子就是 2019 年 MongoDB 收购 mLab，大概就是相似的逻辑。  \n\n当然这个阶段也不是永久的，我说过数据库的终局一定在云端，所以 pCloud 下一个阶段故事的模板大概是 FiveTran + Rockset，变成云端的数据计算平台，但是 pCloud 有更好的基础（拥有全量数据），这个阶段需要引入云端 ETL 和 Serverless 用于降低在云上数据处理和分析的成本，这个阶段是没有天花板的（参考 Snowflake）。  \n\n当未来社区用户需要上云时，这其实就是一个比较巧妙的工具。他们可以通过 pCloud 直接恢复数据到 TiDB 的 DBaaS 上，连导入数据、迁移数据这些工具都不需要了。\n\n## pCloud 完成度离假想的商业模式还有多少工程距离？\n\n**黄东旭**：需要分两部分看，第一是 PiTR 的成熟度，第二个是 pCloud 的成熟度。pCloud 蛮简单的，关键是 PiTR 的成熟度。我会确保它在 PingCAP 的 Roadmap 上。\n\n**栾成**：没错，主要还是 PiTR 本身的质量、性能和所支持的场景。大家都知道， 1TB 数据和 1GB 数据肯定是不同数量级的难度，关键点还是要看这个工具的稳定性以及性是否能满足要求。我记得比赛时 FAQ 有一个问题，如果数据量非常大，出口的 IDC 带宽打满怎么办？我们就需要做一些类似于数据压缩的处理，主要难点在这方面。\n陈昱 ：备份可能永远都是刚需，但做得既易用又好用的云备份确实是比较少的。这东西并不一定要在 TiDB 的生态里面做，本质上它是一个数据库的通用需求，有人愿意的话是完全可以独立成立一家公司，在云上面做 TiDB 或其他任何云数据库的云备份功能，而这也是我看到的这个项目的潜力所在。  \n\n## 参加 TiDB Hackathon 的感受与收获\n\n虽然在 Hackathon 比赛中取得了二等奖，但东旭仍然觉得诚惶诚恐，感叹今年的选手们都太强了。\n\n**黄东旭**：我觉得明年我还是应该去当评委，不当选手了。本来也想做点硬核的项目，但在初赛看到有那么多非常硬核的项目我就觉得心有余而力不足了。以后去当评委，我还可以在评委讨论的时候把一些特别专业的技术语言翻译成人话，给其他评委讲清楚。  \n\n这次 Hackathon 略有一些遗憾，我们有很多想做的功能其实还没有做，比如密钥管理。但是因为 Hackathon 是一个两天的比赛， 需要快速搞个 Demo 出来，但我内心的产品经理之魂是在燃烧的。\n\n**王浩**：因为我不是 PingCAP 员工，也不是数据库社区的人，所以我感觉整个社区的同学都很硬核，有激情。我也感觉到整个社区都特别在意硬核这件事情，所有人好像都认为改内核才是一件很酷的事情。我觉得如果要扩大参赛群体，拿到更多 idea 的话，可以专门设置一两个奖项，给一些看起来比较软的项目，比如一些 PM 那种 idea 的项目，让更多社区外的人也可以参与进来，贡献自己的东西。\n\n**栾成**：我个人也觉得 Hackathon 的项目之间其实很难对比，比如说一个很硬核的性能调优项目和一个很新颖的 idea 之间如何评判是比较困难的。我期望下一届组委会能把这些项目分开评比，独立设奖。\n\n**余峻岑**：今年参赛我感觉还是挺开心的，能够自由写代码，把自己的 idea 做出来，这就是 Hackathon 最吸引人的地方。我个人希望下一次 Hackathon 能够更热闹一些，好吃的多一点。\n\n**陈昱**：我觉得今年最大的感受是项目质量比去年普遍都要高。作为旁观者，我感觉本届 Hackathon 中 PingCAP 以外的参赛者比例大幅增加了，有了更加多元化的 idea 碰撞。其实，TiDB Hackathon 这么一年一年做下来，好做的 idea 肯定都会被做完，这迫使以后选手要想在赛事里脱颖而出，就得去找更加硬核的 idea。\n\n> 延展阅读：点击查看更多 [TiDB Hackathon 2021 优秀项目分享](https://pingcap.com/zh/blog/?tag=TiDB%20Hackathon%202021)","date":"2022-02-24","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"pcloud-as-the-icloud-on-database","file":null,"relatedBlogs":[]},{"id":"Blogs_349","title":"TiDB Hackathon 2021 — 去掉中间商赚差价，TiDB 添加索引性能提升 10 倍！丨黑马警长团队采访 ","tags":["TiDB Hackathon 2021"],"category":{"name":"社区动态"},"summary":"本篇文章将介绍 TiDB Hackathon 2021 黑马警长团队赛前幕后的精彩故事。","body":"在刚刚结束的 TiDB Hackathon 2021 赛事中，首次参赛的“黑马警长”团队， 获得了内核组“三等奖”的成绩。海量数据场景下，TiDB 添加索引速度慢这个问题一直困扰着很多用户，“黑马警长”的参赛项目将添加索引的速度提升了 10 倍以上，是这次内核赛道中绝对的黑马项目。\n\n![三等奖 黑马警长.mp4](https://img1.www.pingcap.com/prod/_e2efceaef5.mp4)\n\n\n<center>黑马警长战队 Demo Show</center>\n\n在本篇文章中，我们将为大家简单介绍这个项目的实现原理和队员们此次比赛的趣闻。欢迎对 TiDB DDL 模块/TiDB-Lightning 有兴趣的同学，联系黑马警长的队员们：\n> 胡海峰(@pingcap.com) github : knull-cn  \n> 李淳竹(@pingcap.com) github : lichunzhu  \n> 曹闯(2546768090@qq.com) github : xcziii\n\n\n我一看到这个项目，就非常的开心，因为这个项目是在我们产品 roadmap 上面的，想不到大家在 TiDB Hackathon 实现了。在 TiDB 里面，add index 是一个比较慢的操作，尤其是在数据量大的情况下面，这个速度极大的影响了用户的体验。我们现在有不少 SaaS 用户，他们的业务变化太快，DDL 是一个非常高频的操作，其中就有不少 add index，所以如果我们 add index 速度越快，就越能提升用户的业务敏捷性，我非常期待这个项目后续的落地。\n\n<p align=\"right\">—— 评委唐刘</p>\n\n## 项目缘起\n\n这个项目的想法源自黑马警长团队成员胡海峰在金融机构的一次 POC 经历。在该 POC 项目中，TiDB  在 online-DDL 添加索引这个环节表现不佳。  \n\n于是，在 POC 结束之后，胡海峰的 Leader 帅鹏找到他，提了这个加速的想法：使用 TiDB-Lightning，一款高速导入数据到 TiDB 集群的工具来添加索引。于是，海峰先找内部 Lightning 研发同事 Gaolei 简单论证了可行性。在聊天过程当中，听说淳竹和龙恒也有类似想法。于是海峰就联系了淳竹，一番探讨之后就和淳竹以及另一位成员曹闯组队报名了。\n\n## 去掉“中间商赚差价”\n\n简单说说这个想法的实现原理。目前 TiDB 添加索引的方式是这样的：TiDB DDL 模块会根据整个表的行数据产生一组索引数据并保存到 TiKV。在线添加 DDL 时，很容易因为表行数据的改变而引发写入冲突。为了避免这个问题，TiDB 会划分数据块，每次取部分数据事务写入 TiKV，TiKV 经过事务层处理后最终保存到 RocksDB。这就导致了添加索引速度很慢的情况。\n\n![01.webp](https://img1.www.pingcap.com/prod/01_a93a53684b.webp)\n\n黑马警长小组的方案是，在准备好多次取表数据本地构造索引数据完成排序后，通过一次性 import 的方式注入到 TiKV 的 RocksDB，使索引数据跳过了事务层，直接走了存储层，**成功避免了事务层耗时，添加索引的时间就大大降低，等于直接把“中间商”去掉**。\n\n![02.webp](https://img1.www.pingcap.com/prod/02_20b353d4ad.webp)\n\n**在整个项目的推进中，黑马警长遇到的最大困难是 “数据正确性” 论证**。作为数据库，数据正确性是最重要的（想象下如果正确性都保证不了，谁敢用你？），之前的添加索引，是通过事务机制来保证索引与数据的一致性。但是，本地编排数据一次性导入到 TiKV 能否保证该一致性呢？  \n\n在仔细查阅源码与资料并请教相关研发后，黑马警长小组最终在理论上证明了该方法的正确性，他们采用两个方式来完成论证：\n\n### 理论论证\n\n在 [TiDB Online DDL 解析](https://pingcap.com/zh/blog/tidb-source-code-reading-17)一文中提到了在线加索引的实现与其中间五个状态，使用 Lightning 添加索引的流程和当前实现基本一致。区别仅在回填数据的处理上，本项目通过以下方式保证一致性：  \n\na. 所有 range 均使用在 write reorg 开始时获取的统一的 tso 读取数据。该阶段往后添加的索引已是写入/删除可见，即 TiDB 插入/删除新的行数据时会一并添加/清理索引数据。  \n\nb. 写入 TiKV 时 Lightning 也将以读取时的统一 tso 写入 KV 数据。当 TiDB 存在增量写入数据可能引发索引改变时，利用 TiKV 的 MVCC 机制可以保证内嵌的 Lightning 可以保证写入的 KV 数据 tso 更小，可以被更新的更新/删除事件覆盖掉。从 TiDB 的视角看，虽然多写入了部分数据，但错写的数据是不可见的，从而保证了索引数据的正确性。\n\n### 测试论证\n\n理论上虽然正确，但需要更多测试保证该论证是正确的。于是，在正确性测试阶段，在不断更新 a 列数据的同时也使用 Hackathon 项目的 TiDB 在线添加索引。添加索引完成后，进行 admin check 确认没有索引不一致问题，进一步证明了理论的正确性。\n\n**项目最终测试结果性能获得了约 10 倍—— 20 倍的提升，而且后续引入并行导入后性能还可以有进一步提升**。  \n\n**最后借这个机会特别感谢以下小伙伴**：  \n\n**胡海峰**：这里特别下我的 Leader @Shuaipeng Yu ，是他提供了 idea，否则就没有这个项目。同时要感谢 @Chunzhu Li 兄，合作愉快！  \n\n**李淳竹**：这里要感谢 @Heng Long 提出了这个 idea，以及要感谢 @Yujie Xia 与 @Lei Gao 对方案正确性和具体实施都给出了非常多的重要意见。没有大家的支持项目落地实施将更加困难。\n当然，同时也要感谢各位产研大佬的无私帮忙，包括：Wenjun Huang\\ Cong Wang\\  Lei Zhao \\ Lei Gao\\ Yujie Xia。\n\n**Q：队名由来有什么故事？**\n\n队名是临时想的，有一次家里小孩在看黑猫警长，我就想着直接叫黑马警长怎么样。黑马也具有突出重围的寓意，最后我们就定下了这个名字。\n\n**Q：是第一次参加 Hackathon 吗？Why Hackathon？**\n\n其实我们去年就想参加，但当时没有特别好的想法，今年有了这个项目的想法后，第一反应就是这个东西似乎有可行性，又不是特别麻烦，觉得可以搞。万一能获奖，还有钱拿。\n所以我觉得反过来说，其实要参加 Hackathon ，一个好的 idea 真的很重要（这里再次感谢下帅鹏与龙恒）\n\n**Q：项目遗憾的地方？**\n\n因为时间关系我们没有在比赛中实现出并行导入，不过我们花了更多时间完善了性能和集群影响的测试 。\n\n**Q：对项目未来有什么展望与期待？**\n\n目前这个项目已经在走合并入 TiDB 仓库的流程，期待以后该方法能成为默认加索引方式，今后广大 DBA 都能飞速地添加索引。\n\n> 延展阅读：点击查看更多 [TiDB Hackathon 2021 优秀项目分享](https://pingcap.com/zh/blog/?tag=TiDB%20Hackathon%202021)","date":"2022-02-17","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"improve-tidb-performance-by-adding-index","file":null,"relatedBlogs":[]},{"id":"Blogs_344","title":"TiDB Hackathon 2021 — 当 TiDB 遇上 Flink：TiDB 高效入湖“新玩法” | TiLaker 团队访谈","tags":["TiDB Hackathon 2021"],"category":{"name":"社区动态"},"summary":"本篇文章将介绍 TiDB Hackathon 2021 TiLaker 团队赛前幕后的精彩故事。","body":"![二等奖 TiLaker.mp4](https://img1.www.pingcap.com/prod/Ti_Laker_1d8ea46deb.mp4)\n\n数据湖是大数据领域近年来非常火热的技术，传统数仓无法实现增量数据的实时更新，也无法支持灵活的元数据格式，数据湖技术便在这一背景下诞生了。数据库的增量变更是数据湖中增量数据的主要来源，但目前 TiDB 的入湖路径还比较割裂，全量变更用 Dumpling 组件，增量变更用 TiCDC 组件。两者处于割裂的链路， TiDB 也无法通过实时物化视图完成数据入湖的实时清洗和加工。\n\n![01.webp](https://img1.www.pingcap.com/prod/01_6f1dbe094e.webp)\n\n在 TiDB Hackathon 2021 赛事中，TiLaker 团队的项目解决了 TiDB 数据入湖的问题。通过 TiLaker 可以帮助用户简化 TiDB 数据到数据湖的流程，充分消化使用 TiDB 上存储的数据。TiLaker 团队也凭借这一项目一举斩获了“二等奖”、“华创资本特别赞助最佳市场潜力奖”、“最佳人气奖”三项大奖。  \n\n> “去年 Hackathon  其实有不少跟 Flink 整合的项目，今年决赛就看到一个，我还是有点小失望的。但今年 TiLaker 做的还是挺完备的，有 Flink committer 的参与，给 Flink 实现了一个 CDC Connector，这样能让 Flink 直接读取 TiDB 的增量数据，同步到下游。借助 Flink 的能力，让 TiDB 更好地与下游生态进行打通，后面也希望有更多的应用案例能出来。”\n> <p align=\"right\">——评委唐刘</p>\n\n在过去的一年中， TiDB 非常重视生态建设，在生态中最重要的就是 TiDB 作为一个分布式数据库和大数据生态之间的融合互操作。TiLaker 通过 Flink CDC 建立了一个快速、高效、简化的通道，解决了高效入湖的问题，将两个生态进行了更好地融合。本篇文章就将通过对 TiLaker 团队与华创资本合伙人谢佳的对话，揭秘 TiLaker 赛前幕后的精彩故事，也希望给开发者和用户们如何将数据入湖带来一些启示。\n\n## TiLaker 团队的由来：缘起社区\n\nTiLaker 团队成员由四位来自 TiDB 社区和 Flink 社区的资深贡献者和开源软件爱好者组成，下面先来认识下他们：\n\n**吴雪莲**：TiDB 同学可能对我比较熟，我一直在 TiDB 做内核，也是 TiDB Committer & TiKV Committer。有个爱好就是喜欢去撩 Flink 的同学，我爱人就在 Flink 团队做数据湖，这次也因为这个渊源与 Flink 的小伙伴走到了一起。\n\n**徐榜江（雪尽）**：我之前在阿里网络团队一直做实时监控系统，后来觉得实时计算是一个很好的方向，就跑来 Flink 社区，大概做了两三年时间。前两年专注在 Flink SQL 上，后面慢慢在数据集成方向发现了一些很大的空间。很多时候 Flink 被人们拿来当成一个数据管道，但数据管道是非常薄的一层，不像数据库、数据湖有着数据的强依赖性。所以我们就有了 Flink CDC 这个项目，它相当于给 Flink 这个管道增加了一个集成能力，可以支持更多的数据源、更多的上下游。我最近这大半年都在做 Flink CDC ，现在也是 Flink CDC Maintainer & Apache Flink Committer。\n\n**蒋晓峰（子懿）**：我叫蒋晓峰，阿里的花名叫子懿，和雪尽都来自 Flink 团队。我是 Apache ShardingSphere & Apache RocketMQ Commttier，现在主要负责 Apache Flink AI 相关的工作。算上本次比赛一共参加了三届 TiDB Hackathon 。\n\n**蒋泳波**：我目前是在 TiDB 调度团队做研发，和雪莲是同一个组的同事。我其实是最近才加入 TiDB 的，之前在阿里网络部门做数据开发，和雪尽老师都在一个网络大团队。不过我加入阿里的时候，雪尽好像已经离开了当时的团队，我维护的一些 SQL 就是雪尽留下来的。\n\n从个人介绍不难看出，TiLaker 的四位成员之间其实非常有渊源，TiLaker 的故事也缘起于此：  \n\n时间回到 Hackathon 开启报名时——  \n\n有一天吴雪莲回家，她爱人对她说：**我有个同事想找你组队**。\n\n**蒋泳波**：这个人就是我，当时我在参赛群里看见了雪尽，虽然以前和他并没有直接交流过，但还是去私聊了下，问要不要一起组队玩？之后雪尽又联系了子懿，我又联系了雪莲。  \n\n就这样，TiLaker 团队正式组成了。\n\n## 两个社区的交叉学科\n\n比赛中，TiLaker 团队给投资人评委华创资本合伙人谢佳留下了深刻的印象，他一直对这类 Infra 的项目非常感兴趣。\n\n**谢佳**：在这次整个参赛的选手和项目中，TiLaker 的项目是非常具有代表性的。两个非常受开发者喜爱的顶级社区之间，相互放大彼此的生态，进行互联互通。数据入湖来自于产业界非常广泛、实际的需求，对于 Flink 的同学来说，可能这个事情他们或早或迟都会去做，**本次 Hackathon 活动恰恰加速了 Flink 和 TiDB 社区的迭代**。从团队方面来说，大家都是开源社区中的各种好手，都能独当一面。这几方面合在一起，就是非常能吸引我的点。\n\n**雪尽**：两个社区的人做一个集成类的项目，相当于一个交叉学科，我们的团队拥有 Flink 与 TiDB 两个社区的同学，对于做这样的集成类项目或生态类项目是很有帮助的。比如，有一些 TiDB 技术的细节，我可以很快地问一下雪莲老师、泳波老师，他们可以快速地给我答案，我就不用去 GitHub 上去看代码和文档了。  \n\n我和子懿对 TP 类型的数据库其实是没有多少经验的，我对 MySQL 、PG 、Oracle 有一定了解，但对 TiKV 底层的更新机制、集群其实不是很了解，这些都是通过这次 Hackathon 了解的。所以刚开始我们对 TiDB 的一些逻辑不是很清楚，刷了两次夜才解决。后来在雪莲和泳波进来后，有一些代码看不懂的时候，我们就会在群里直接交流，节省了很多时间和精力。\n\n### 项目的灵感来源\n\n**吴雪莲**：项目的名字是才华横溢的子懿老师起的，包括我们的战队宣言，还有答辩 PPT ，以及团队介绍视频都是他想的。项目的实现机制主要由雪尽老师提出，他平时就一直在做 Flink CDC 的工作，上游接了很多数据库，有很多 TiDB 用户就找过来问能不能支持一下 TiDB 。恰好这时，我们看到 TiDB Hackathon 2021 开启报名，于是就决定带着这个项目参赛了。\n\n**雪尽**：Flink CDC 在数据源方面， 其实主流的 DB 都支持了，即使没有支持，社区的 PR 也都开出来了，只是我这边没有精力来得及给大家 review 。像 MySQL 、Oracle 、PG 、 MongoDB 、TiDB 的 PR 都在整理中，阿里的 PolarDB 和 OceanBase 的同学看到我们来 TiDB Hackathon 比赛也过来开了 PR，最近也在催着 review。  \n\n其实 Flink 这个管道有着很强的集成能力，它可以连接到很多下游。当数据到了一定规模时，数据库的存储始终要比廉价的数据湖存储更贵。很多历史数据并不需要那么贵的存储，也不需要去分析。让它直接往数据湖里导入，做历史存储就够了。而且数据湖也有更新的能力， Flink 结合数据湖甚至能够做到分钟级的更新。**数据库接 Flink 再接数据湖，就是看中了数据湖既便宜又可以更新这两大核心优势**。\n\n### 这次 Hackathon 上实现了哪些内容？\n\n![02.webp](https://img1.www.pingcap.com/prod/02_f645b43a3c.webp)\n\nTiLaker 基于 TiCDC 组件开发了面向 TiDB 的 Flink CDC Connector， TiDB CDC Connector 提供全量读取历史数据和实时读取增量数据的能力，在全量和增量数据切换时，保证一条不丢，一条不多的 eactly-once 语义；同时，TiLaker 提供了 SQL API，用户只需要几行 Flink SQL 就能捕获 TiDB 中全量的历史数据和增量数据。得益于 Flink SQL 的 c hangelog 机制，Flink SQL 可以和数据库的变更数据无缝衔接，通过 Flink SQL 定义的 tidb-cdc 表就是 TiDB 中对应表的实时物化视图，每次数据库中的变更都会让 tidb-cdc 表自动更新；\n\n![03.webp](https://img1.www.pingcap.com/prod/03_f7b226d84a.webp)\n\nFlink CDC 项目还提供了 MySQL、MariaDB、Postgres、Oracle、Mongo 等数据库的支持，这意味着在支持 TiDB 后，用户可以实现异构数据源的融合，比如部分表在 MySQL 中，部分表在 TiDB 中，可以做实时的 Join、Union 等 Streaming 加工；此外，作为一个优秀的计算引擎，Flink 可以提供强大的计算能力和优秀的 pipeline 能力，支持业界多种数据湖产品(Hudi，Iceberg)，并且提供 SQL API 支持。这让 TiDB 的用户只需要使用 SQL 就可以方便地将数据实时写入数据湖，轻松实现数据湖的构建。\n\n正如评委唐刘评价所言，TiLaker 团队在 Hackathon 中实现的项目已经非常完备，对于比赛他们已经完成了一大半，接下来摆在大家面前的难题，就是如何在比赛中让评委对项目的亮点更有体感？\n\n**吴雪莲**：主代码和 Flink CDC 主要是雪尽老师和子懿老师在弄，我跟泳波是打酱油的，主要精力放在做 demo 上。当时一直在想怎么才能突出这个项目的亮点呢？我们当时就想到了网约车实时智能调度系统。\n它基本上模拟了网约车是怎么调度的。实时的数据写 TP 的时候都会写到 TiDB，但是像一些推荐的数据，比方说一个乘客要打车，最简单可能就是推荐一下他附近的车辆。在这个大数据的情况下， TiDB 可能就不太够用。我们借助 Flink CDC 将数据导入到 Flink 来计算，实现实时推荐业务。另外在数据入湖后，还做了一个报表，就是那个车跑来跑去的报表，这些数据都是我们从湖里面拿过来的，相当于一个离线的分析。\n\n**蒋泳波**：当时想做这个 demo 主要就是觉得网约车是一个比较典型的互联网架构，它会有一些订单交易的核心系统，这个系统需要数据，这一定是要跑在 TP 数据库上面的。然后它也会有一些实时计算的要求，但是一般 TP 系统是很难去做流式计算的，同时对运营同学来说也会有一些实时大屏的需求，需要方便他们去做一些业务分析。\n\n## 对 TiLaker 未来有何期待？\n\n**雪尽**：从我的经验来看，一个项目真的要上生产的话，还有蛮多事情要做的。特别是在测试方面要花很大的精力，以我最近对各个数据库的了解，不同版本之间各种兼容性的坑其实是特别多的，如果要为银行这样的客户提供服务，还有蛮多的路要走。\n\n**蒋晓峰**：在实时机器学习场景里，我们这一套 TiLaker 方案对用户来说是非常友好的。现在机器学习更加实时化了，它会带来很多实时特征的存储。现在大部分公司的实时特征存储都用的是 KV， 比如 Redis ，它就要把每个时间点的特征都存下来。但如果用了 TiDB + TiLaker 这一套解决方案，客户就可以减少特征存储成本。我平时主要是负责实时风控和实时推荐解决方案的，也会对接很多客户，如喜马拉雅，他们都会有这方面需求，而且需求很大。这个项目如果可以落地，是可以作为一个商业化解决方案的。\n\n评委**谢佳**从投资人的角度也给出了自己的看法：“坦白讲，其实这类产品在商业化方面会有一些挑战。这类产品会比较偏向于解决中间某个环节的问题，但凡做中间层都会面临一个商业上的悖论和挑战——你解决的确实是大家普遍遇到的问题，但还不是一个完整的商业问题。它会带来一定程度上的效率提升，但是对于商业的价值提升不是很直接。如果你能从中间环节往整个业务角度看的话，它的价值链上下游就能够延展得更多。客户拿到这个产品，就是一个完整产品，他用这个完整产品可以解决更多的问题。从商业化的角度来说，就更容易创造更多的客户价值。另外，很多企业都会有一些特定需求、非标化的场景，你很难用一个产品来满足全部需求。但未来如果大家都上云了，更加标准化了，就会扫除很多商业化的障碍。”\n\n## 参加 TiDB Hackathon 的收获与期待\n\n**吴雪莲**：我之前当过导师，也当过围观家属，但今年确实是真正意义上第一次参加 TiDB Hackathon 。我其实一直挺想对 Flink 与 TiDB 生态接触的东西了解一下，就趁这个机会去了。通过 TiLaker 这个项目，我对 Flink 以及 Flink 下游的一些生态更加了解了，这对我在 TiDB 的工作有很大帮助。另外，通过参加 Hackathon ，我在杭州现场和很多搞开源的同学都交流了一下，还是挺开心的。\n\n**雪尽**：我也是第一次参加 TiDB Hackathon。虽然 Flink 社区之前也有举办过，但其实跟 TiDB 早期举办的 Hackathon 应该差不多，就是两天的极限编程。这次组委会给我们留了比较充沛的时间，也是我们最终能把这个项目的完成度做得比较好的一个原因。  \n\n本届 Hackathon 真的就是高手如云，我觉得很多参赛选手的 idea 和实际效果都非常厉害。我们本来都没期待能够拿二等奖，感觉最多就是三等奖。我记得有一个做性能增强的团队，他们的 Benchmark 测出来最低提升 18%，最高 40%，那种项目的确很有技术含量。另外，在杭州这边还有一个最佳创意奖，和游戏做结合的，给我的印象也很深刻。参加 TiDB Hackathon，能够认识社区的各个同学，我觉得这个收获更大。\n\n**蒋晓峰**：我已经想好了下一界 Hackathon 比赛的 idea。Flink Forward Asia  2021 提出了 Streamhouse 概念，其中引入了 Dynamic Table Storage 。我想用 TiFlash 作为 Dynamic Table Storage 底层的实现，这样可以更加强 Flink 生态和 TiDB 生态之间的整合。这不仅仅是在数据集成方面做对接合作，也可以在其他模块上面做一些创新。\n关于 Hackathon 我期待之后的 Hackathon 能在线 PK 写代码 。这次可以看到很多参赛项目的工作量不仅仅只有两天能做完，其实从 Hackathon 比赛的意义来说就不那么符合要求。\n\n**谢佳**：我是第二次参加 TiDB Hackathon 了。第一次参加的时候大家总会说 PingCAP 是一家 Hackathon 驱动的公司，我当时没有特别强烈的感受，但这次我觉得这种感受还蛮强的。在国内做基础软件的企业中，PingCAP 应该是第一家拥抱开源，同时把商业化也做得不错的。很多人平时可能偶然会产生一些 idea ，但因为工作例行安排平时做不了，通过 Hackathon 就能把这些 idea 释放出来，变成另外一种 driven。\n\n> 延展阅读：点击查看更多 [TiDB Hackathon 2021 优秀项目分享](https://pingcap.com/zh/blog/?tag=TiDB%20Hackathon%202021)","date":"2022-02-10","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"when-tidb-meet-flink","file":null,"relatedBlogs":[]},{"id":"Blogs_343","title":"TiDB Hackathon 2021 — Ti-Click：通过浏览器快速搭建 TiDB 在线实验室 | Ti-可立刻团队访谈","tags":["TiDB Hackathon 2021"],"category":{"name":"社区动态"},"summary":"本篇文章将介绍 TiDB Hackathon 2021 Ti-可立刻团队赛前幕后的精彩故事。","body":"![Ti可立刻.mp4](https://img1.www.pingcap.com/prod/Ti_e0dfdccd3c.mp4)\n\n> Hackathon 大赛中的点子和项目有很多， 团队中这种协同合作，不畏困难，相互扶持的团队精神更是可贵。所以 Hackathon 的奖项在我们心里算个事儿，因为他毕竟代表了评委对我们项目的认可；但是没获奖也不算什么大事儿，因为有这样的团队在，夫复何求！\n> <p align=\"right\">—— Ti-可立刻</p>  \n\n在 TiDB Hackathon 2021 赛事中，Ti-可立刻团队开发的 Ti-Click 项目通过在线 IDE 的方式，快速搭建基于 TiDB 的 Example App 的开发和在线编译的实验室，**可以提高用户的 TiDB 生态初体验**。 此外还可以让用户在线尝试包括 TiDB Cloud 服务在内的多项服务，**降低 TiDB 生态的尝鲜复杂程度**。Ti-Click 项目收获了评委和观众的一致赞赏，并最终晋级了本届 Hackathon 的 20 强。\n\n> “TiClick 是我最喜欢的一个项目，我个人给了最高的分数，并不是因为 Sai 同学激情的演讲，也不是因为炫酷的 web 界面，**而是我看到了 TiDB 如何更好地吸引开发者的一个方向**。针对开发者学习 TiDB，后面我相信大概率就是一个 SaaS 服务，开发者直接通过浏览器就能学习了解 TiDB。这个项目让我看到了落地的可行性，我也希望能快速落地。不过我也知道，我还是希望能先在 TiDB Cloud 上面支持 Github SSO 登录，支持 open API，变得对开发者更加友好，这样才能为后面的生态扩展打下基础。” \n> <p align=\"right\">——评委唐刘</p>  \n\n## 是什么促使你们三位组队？\n\n我们三人都是来自于用户、社区和市场一线的同事。我们认为能组成一个队伍除了缘分，还是因为对  TiDB 社区的执着信念。我们的团队甚至还有日本地区的第一位 TiDB 认证讲师。我们一致认为共赢 TiDB 社区的信念是把我们凝聚到一起的力量。\n\n## “Ti-可立刻”队名的故事\n\n我们发现不光是 TiDB，包括很多 Infra 产品（基础软件）都有触达消费者难的问题。也就是说仅仅用文档来告诉开发者如何使用产品，但是并没有理解开发者的期待。**其实作为一个开发者更期待的是上手试一试**。虽然各个厂商都推出了试用版的免费优惠政策，但是要知道，具有 Infra 产品属性的产品，其实开发者上手是很难的。最终还是面对为啥要尝试 （Why），尝试什么（What）和 怎么尝试（How）的困局。我们觉得与其让开发者来思考这个问题，不如我们来帮他思考。\n\n所以 Ti-Click 从一开始就对接了 TiDB 和 TiDB Cloud 两款产品，而且带有完整的教学引导（Why），同时提供了基于 Java、Python、Golang、Nodejs、Django、PHP、Laravel、Springboot 等语言或者框架的丰富的式样案例（What），只要在浏览器里面点击一下，就可以通过浏览器，在云端轻松部署一个式样程序（How）。\n\n**Ti-可立刻，可以立刻使用**，当然也是 Click 的谐音，我们认为是非常符合我们对产品定义的，同时也传达了我们的理念。\n\n## 分布在三个时区的国际化战队，如何面对 Hackathon 紧张的项目准备工作？\n\nTi-可立刻战队作为历年 Hackathon 首个全部队员都分布在不同国家、不同时区的国际化战队，在队伍成员之间的分工和项目推进上都面临很大挑战。\n\n在队员的分工方面，在 12 月 22 日确立组队后，就开始着手进行开发。其中 Pheobe 因为之前主研文档、培训方向，所以在 Ti-Click 主要是负责项目的宣传和产品的定位，本次的视频也都出于我们的大才女之手。杜志刚老师主要负责 PHP、Golang 的产品 Example 开发和难点项目攻克，比如本次大赛中，我们将 Colopl 团队开发的 Laravel 组件导入的这一绝妙案例，就是杜老师的神来之笔。成臣主要负责整个平台的搭建，以及 Java、SpringBoot、Node.js 和 Python、Django 的 example 开发。\n\n在项目整体推进上面，因为我们都有多年工作经验，所以明确分工后，大家还是非常明确地推动项目前进的。我们没有设定时间线，但是基本上大家都在合理的时间点将作品拿出来了。而且作品的完成度非常高，基本上都是最终演示的版本。团队成员即使背靠背，也会定期汇报当前的开发进度，让队友放心，每个人对自己要实施的项目都有强烈的 Owner 精神。所以与其说是安排项目推进，不如说我们是一个内在驱动型的典范。\n\n## 关于 Team Work\n\n在 Hackathon 筹备和进行中的很多时候，当遇到突发情况，我们也都会主动站出来，挑起重担。比如说我们团队本来想由 Pheobe 在线讲解。但是面对答辩需要现场讲解的要求时。成臣主动担起重任，在现场进行项目讲解。这期间，我们准备了一遍又一遍的试讲，最终我们幸运地在预选赛中出线。在得知可以参加决赛后，我们又开始马不停蹄地准备复赛。成臣全力以赴地准备决赛演讲，杜志刚和 Pheobe 则通宵达旦地赶制了对 Ti-Click  Ecosystem 的讲解视频。\n\n整场活动除了参加比赛以外，我们还需要处理手头的很多工作，大家基本上是 24 小时马不停蹄。比如说亚太地区的伙伴凌晨 1 点交接给北美的伙伴，北美的伙伴再在亚太时间下午交接给亚太区的伙伴。这也铸就了“把我的后背放心交给队友”的团队情感。\n\nHackathon 大赛中的点子和项目有很多， **团队中这种协同合作、不畏困难、相互扶持的团队精神是更是可贵**。所以我们也想把 Ti-可立刻这种团队精神分享给大家。\n\nHackathon 的奖项在我们心里算个事儿，因为他毕竟代表了评委对我们项目的认可；但是没获奖也不算什么大事儿，因为有这样的团队在，夫复何求！\n\n## 关于 Ti-Click  项目\n\n现在 TiDB 对广大受众可得的信息，无论是文字、视频还是互动性教学，更多的是以数据库本身为核心。比如：如何建立一个分布式 SQL 数据库，这样的数据库优势在哪里，如何跑起一个 TiDB Cluster，试试 TiDB SQL 等。**我们希望打造的视角，是从软件开发整体生态中，应用程序开发者的角度来看待，如何连接、使用 TiDB**。虽然 TiDB 可以兼容 MySQL 5.7，但是还是会有一些差异，此外，不同版本间的的差异也是存在的，为了让 Java/Python/Node.js/Golong/PHP/C# 的应用程序开发者可以更加快速的尝试TiDB，并且直观的了解到面对这些差异性如何通过代码进行处理。有了这个直观的互动基础，开发者就会更加有意愿了解 TiDB 的优势和长处，比如 TiDB 的拓展性优势、虽然是分布式数据库，但是依旧保证了数据的强一致性、OLAP 和 OLTP 两手抓两手都要硬等等。\n\n![1.png](https://img1.www.pingcap.com/prod/1_27963e6484.png)\n\n## Hackathon 之后对项目进展有什么最新计划？\n\n一方面，我们想将 Ti-Click 的研发推进下去，例如使用轻量级虚拟机替代普通容器，防止容器逃逸的安全策略改善，以及相关的周边测试样例追加。另一方面，我们也会在更多领域提供针对开发者、DBA 以及架构师的不同的产品系列，让整个产品的使用体验感受的大幅度提升。\n\n> 延展阅读：点击查看更多 [TiDB Hackathon 2021 优秀项目分享](https://pingcap.com/zh/blog/?tag=TiDB%20Hackathon%202021)","date":"2022-02-08","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"ti-click","file":null,"relatedBlogs":[]},{"id":"Blogs_341","title":"TiDB Hackathon 2021 — ChaosCraft：和女朋友一起来 Hackathon 表演绝活丨滑滑蛋团队访谈","tags":["TiDB Hackathon 2021"],"category":{"name":"社区动态"},"summary":"本篇文章将介绍 TiDB Hackathon 2021 滑滑蛋团队赛前幕后的精彩故事。","body":"> 根据马斯洛需求层次理论，当基本的生理和安全需求被满足了之后，人们就需要去满足更高级别的精神级别的需求。\n> <p align=\"right\">—— 周志强，滑滑蛋队长，PingCAP Chaos Mesh 开发工程师</p>  \n\n![无限创意奖 滑滑蛋.mp4](https://img1.www.pingcap.com/prod/_ae44b10269.mp4)\n\n当 TiDB 集群以一群小羊的形象出现在你面前，还咩咩叫的时候，可能再严肃的程序员都会感受到“更高级别的精神抚慰”。所以在刚刚结束的 TiDB Hackathon 2021 赛事中，当滑滑蛋团队在 Minecraft 里展示 Kubernetes 工作负载并进行混沌实验的时候，场面一度十分欢乐，就好像突然从《今日说法》穿越到了《欢乐喜剧人》。ChaosCraft 也在众多严肃、硬核的项目中脱颖而出，摘得了无限创意奖。\n\n![01.webp](https://img1.www.pingcap.com/prod/01_33df8ea243.webp)\n\n今年是滑滑蛋团队第二次参赛，用队长周志强的话来说，就是再一次带着女朋友一起表演绝活，去年的绝活是 TiDB 驾驶舱，大家都笑称这个项目提前预测了元宇宙的到来。但去年的项目没有获奖，周志强表示拿奖并不重要，重要的是你做的事情得到别人的认可，拿奖是一种被肯定的方式，给大家带来欢乐也是。跟周志强聊的整个过程都很欢乐，也希望你能在文章中感受到。\n\n## 队名的由来\n\n![02.webp](https://img1.www.pingcap.com/prod/02_5b230092aa.webp)\n<center>图片来自网络</center>\n\n我和女朋友都是那种二次元比较宅的人，“滑滑蛋”这个名字就来源于日本番剧轻音少女主题曲《Fuwa Fuwa Time》的空耳名。因为一看到这个名字就会想到剧中的主人公们以一种非常轻松惬意的方式来做自己想做的事情，这也是我比较羡慕的一种状态。\n\n## 为什么选择做一个看起来没什么用的项目？\n\n我觉得无论是什么事情，一定要有趣，才会做得久。我在生活中是一个比较活泼的人，在和其他软件工程师交流的过程中，会发现他们的工作或是思想都过于沉重，总想着做很多非常酷但是没那么 funny 的事情。但我觉得人生还可以做很多好玩的事情，而且 Hackathon 又没有拒绝说不能做“娱乐”项目，所以才有了来 Hackacthon 上整活的念头。\n\n而且带给人快乐是一件比较容易获得反馈的事情，如果你要做一个性能提升的硬核项目，可能评委需要思考项目落地的成本和人力，以及如何让这个项目产生真正的成果。但是我们这个项目不会落地，所以大家看了就只有快乐，快乐就会表现在脸上，就很直接。也希望和我有类似想法的人不要恐惧，不要害怕，TiDB Hackathon 是一个非常 nice 的机会，大家不会因为你做的东西不严肃就 judge 你。\n\n## 项目灵感来自哪里？\n\n我本科的专业是数字媒体技术，在大学里也学过一部分游戏相关的知识，所以对于“游戏”是比较亲切的。而且对于我来说，“游戏”可以作为一种新的艺术形式，它在视觉听觉，甚至在触觉上都可以对人的感官进行刺激。游戏本可以用来做更多的事情，只是当前的社会大多用这种艺术形式或者说是技术来制作架空世界，或者说是游戏了。\n\n![03.webp](https://img1.www.pingcap.com/prod/03_057d8f95ab.webp)\n<center>滑滑蛋去年的参赛项目：TiDB 驾驶舱</center>\n\n去年第一次参加 Hackathon 的灵感来源于梦龙哥的一篇[博客](https://disksing.com/hackathon-idea/)，因为我大学专业的原因，所以很自然地想到了使用 VR 来做一些现实中很难做到的事情。去年参赛的时候，因为其他人做的项目都是比较严肃的项目，我也一度担心会不会因为风格不合被踢出赛制，但大家的反馈都是比较积极正面的，所以今年还是继续以 “给大家带来欢乐” 的方式来参加比赛。\n\n![04.webp](https://img1.www.pingcap.com/prod/04_838706eeb3.webp)\n<center>KubeInvaders 项目展示，图片来自网络</center>\n\n今年参赛的灵感来源是一些混沌工程相关的游戏，比如说 KubeInvaders，用击坠外星人飞船的方式来模拟杀 Pod。这个项目在 KubeCon 上也有一个演讲，所以全世界都会有工程师去关注这种没什么卵用，但非常好玩的项目。\n\n## 很多伟大的发明也是从看起来没什么用的创意开始的，你觉得你们的项目会有这个潜力吗？\n\n它本身确实没什么用，但就像人类在打字机的时代想象不到可以用鼠标在网页上点点点的场景，我们现在拿鼠标去点网页的时候，也很难想象未来更先进的操作交互方式是什么样子的。\n\n我觉得使用 3D 的方式展现数据以及进行交互，未来一定一定会有非常大的潜力，但是这类项目估计会慢一些。在未来，更为舒适的交互方式一定是会从浏览器中，从移动应用中，进入到 AR 眼镜里去；到那时候，“游戏引擎”里的哪些计算机图形学技术才会大放异彩。\n\n## 如何轻松、欢乐地参与 Hackathon ？\n\n我们的项目是在 Minecraft 中操作 Kubernetes 相关的工作负载，Kubernetes 相关的主要是我写的，Minecraft 相关是她写的，比如为什么羊的头上会有一个名字这些主要是她在玩的。另外就是我们的主程 GitHub Copilot，帮助补全了很多图形学的代码，极大地降低了 Coding 的成本。\n\n项目推进就基本是散养了，完全按兴趣做，想到哪做哪，用一种快乐、轻松的心态去完成的。\n\n**Q 在比赛过程中你们遇到过什么比较大的技术困难？是如何解决的**？\n\n**周志强**：比较大的问题是 Minecraft 的 Modding 问题，因为 Minecraft 没有官方的模组 API，也没有文档，在修改的时候只能去猜该用哪些 API。这里要再次感谢 GitHub Copilot，基本上你给到一个 function name，然后用人类的语言告诉它要做什么，就可以自动补全里面 function 的实现，非常方便。\n\n**Q 这次 Hackathon 的时间有限，你们在比赛过程中有什么遗憾？在组队及参赛过程中有什么有趣的事儿可以分享吗**？\n\n**周志强**：没有什么太大的遗憾。项目上确实有很多由于赶时间出现的工程问题，但是这都是正常的，任何项目都会有。另外就是很多想到的 feature 还没有实现得非常好。比如我们在 Minecraft 中用网络水晶来指工作负载，网络水晶之间的光束就代表网卡间的数据传输，但暂时没体现出数据量的大小。因为我之前做过运维人员，对于运维来说，如果机器出现了一个热点，网络流量是一个非常重要的指标，所以如果能展现出网络流量的大小，是非常有用的。\n\n![05.webp](https://img1.www.pingcap.com/prod/05_82ec2f9261.webp)\n\n趣事就太多了，比如当第一个头上顶着名字的羊出现在你前面咩咩叫的时候，是非常开心的。我平常用来创建 Pod 的一条命令的输出，竟然能对应上眼前的一只羊，真的非常好玩。另外就是做 presentation 的 PPT 的时候，也比较有趣，我俩是几乎全程笑着做完的。\n\n**Q 对这次比赛你们的体验如何**？\n\n**周志强**：体验还不错，只是人越来越懒了，下次估计是想纯线上参与了。我本来也是在 remote 工作，习惯了家里的开发环境和网络环境，我又非常不想提前录制 demo 视频，因为觉得有太多作假的可能性，所以在预赛的时候翻车了。可能是 PPT 打动了大家，才让我有机会进入到后面的第二轮展示。\n\n## 展望与期待\n\n**Q 你们的项目这次获得了无限创意奖，对这个项目未来有什么展望与期待**？\n\n**周志强**：希望能继续维护下去，也希望有兴趣的同学来搭把手。这里也有一点小遗憾，大家都欢乐了，但是木有人激动到想来一起来维护。\n\n项目地址：https://github.com/fantastic-things/chaoscraft\n![06.webp](https://img1.www.pingcap.com/prod/06_457711e163.webp)\n\n**Q 期待明年的 TiDB Hackathon 有哪些改进**？\n\n**周志强**：期望有更多的整活人来展示绝活，明年做的时候能找到更多的队友，因为去年和今年都是我跟女朋友 2 个人去做的，如果有更多的人，我们可能会做得更好一点。当然如果大家有什么好点子，也欢迎来找我，很开心和大家聊这个事情。\n\n> 延展阅读：点击查看更多 [TiDB Hackathon 2021 优秀项目分享](https://pingcap.com/zh/blog/?tag=TiDB%20Hackathon%202021)","date":"2022-01-27","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"chaos-craft","file":null,"relatedBlogs":[]},{"id":"Blogs_340","title":"TiDB Hackathon 2021 — 把复杂交给我们，把简单还给你丨TiVP 让 SQL 执行计划可视化","tags":["TiDB Hackathon 2021"],"category":{"name":"社区动态"},"summary":"本篇文章将介绍 TiDB Hackathon 2021 TiVP 团队赛前幕后的精彩故事。","body":"> 通过 TiDB Hackathon 重新认识了自己的潜力。当你想做一件事情，你会发现自己特别专注在上面，然后一些你觉得不会成功、不可能的事情也会变得可能。\n> <p align=\"right\">—— TiVP 团队</p>  \n\n![三等奖 TiVP.mp4](https://img1.www.pingcap.com/prod/Ti_VP_b2ce5a04cd.mp4)\n\n在刚刚结束的 TiDB Hackathon 2021 赛事中，TiVP 赛队的作品 TiDB Visual Plan 实现了 SQL 执行计划的可视化，有利于快速定位及解决执行计划相关的各类问题。由于项目的实用性和从用户角度出发（无论是外部 TiDB 用户，还是 PingCAP 内部研发工程师），摘得了 “三等奖” 和 “用户之选奖”。\n\n> 项目非常聚焦，有效提升了执行计划的可读性，具备一定的索引推荐能力。\n> <p align=\"right\">——评委冯光普</p>\n\n> 当我终于看到可视化的执行计划时，我几乎流下了激动的泪水。毕竟我们之前诊断慢 SQL 实在是太苦了，那么一大屏的执行计划，几乎叫做没法看，而且如果要对比两个执行计划的异同，就更崩溃了。有了可视化，至少分析到底哪里慢的效率会提升很多。\n> <p align=\"right\">——PingCAP 研发副总裁唐刘</p>\n\n## 为什么做这个项目？\n\nTiVP 是一支由 PingCAP 员工和社区小伙伴临时组成的队伍。在 PingCAP 入职不到半年的 Yves 看到 Hackathon 的宣传，抱着体验下的心态报了个名。作为产研消防队的一员，Yves 在日常工作中会经常看客户执行计划方面的问题，最开始他只有一个朴素的想法：TiDB SQL 调优的需求很大，客户申请的原厂支持里，与执行计划（Plan）相关的问题就过半；SQL 作为一种声明性语言，观察执行计划是排查执行效率的唯一手段，慢 SQL Explain 出来的执行计划异常复杂难懂影响分析效率。在强调软件“可观测性”的今天，能不能做 SQL 执行计划的可视化？\n\n于是他私底下找到身边优化器大佬 Chrysan 聊这个想法，没想到刚聊两分钟就一拍即合，然后大佬拉来了 QA Tammyxia，于是阵容突然就庞大了。但是仨人都是做数据库后端的，可视化可视化，没有前端可不行。抱着试试看的心态，Yves 就在 AskTug 上发了个队友招募贴。\n\n![01.webp](https://img1.www.pingcap.com/prod/01_c739fe2413.webp)\n\nTiDB 开源生态强大的感召力，让第二天就有好几位小伙伴找 Yves 交换了联系方式，其中 92hacker（陈元，在深圳的一个前端开发大牛，尽管其工作内容与数据库不强相关，但一直关注 PingCAP 公众号，了解 TiDB 进展） 与他进行了第一次友好深入的交流，于是队伍就这么拉出来了。\n\n团队的名称 TiVP 是 TiDB Visual Plan 的缩写，大家觉得 VP 也很霸气，且 PingCAP 有许多以 Ti 打头的工具，于是团队就一致通过了这个队名。组完队后距离提交 RFC 还有一段时间，团队浏览了 Hackathon 2020 的获奖项目，还跟往届选手做了经验交流，正如 TiVP 团队所言，dream big、冠军心，这次首次参赛就获奖，一个原因就是目标定得高。\n\n## 项目解决了什么问题？\n\nTiDB Visual Plan，通过收集 TiDB 数据库侧 SQL 的执行计划和运行时信息，基于开源组件 dalibo/pev2 开发了一个显示界面用于图像化呈现 SQL 的执行计划，对庞杂数据库输出的信息做分类梳理，帮助技术人员更便捷地了解、分析 SQL 语句及其执行逻辑，并可对问题关键高亮提示，从而快速定位以及解决执行计划相关的各类问题，如慢 SQL 优化、执行计划选错等。\n\n![02.webp](https://img1.www.pingcap.com/prod/02_55aa0dfadc.webp)\n\n如下图所示，TiDB Visual Plan 会将左侧执行的 SQL 语句，进行 JSON 转换和相应算子的统计，并以树形的结构清晰展示执行计划。每个算子点击展开后，会显示其具体的耗时、条数及所使用的资源。算子右上角还会用各类图标对一些问题进行提示，如耗时比较长、资源消耗比较高、执行计划预估和实际执行条数出现较大偏差等，通过这些提示，DBA 就能很方便地定位问题模块进行细节排查。\n\n![03.webp](https://img1.www.pingcap.com/prod/03_3d9ca0b9da.webp)\n\n针对复杂的 SQL 执行计划，TiDB Visual Plan 还将提供 Advisor 功能，通过 Hint 提示（如下图的 use_index）和后台计算，对比优化前后的变动情况，并可通过 “Apply” 一键应用优化，实现智能辅助调优【注：该功能为蓝图规划，本次 Hackathon 仅演示交互流程】。\n\n![04.webp](https://img1.www.pingcap.com/prod/04_49c59de2a0.webp)\n\n此外，TiDB Visual Plan 还可通过耗时分析、代价分析等不同维度对 SQL 执行计划进行可视化，提供树形图和经典横向扩展模式，总之你想要的，这里都有。\n\n![05.webp](https://img1.www.pingcap.com/prod/05_940362f4c5.webp)\n\n## 比赛中的挑战与趣事\n\nTiVP 团队的 4 名成员都是首次参加 TiDB Hackathon，作为混编队伍，整个参赛过程充满了挑战与欢乐。如 92hacker 谈到的，非常荣幸通过社区找到三个 P 社小伙伴，让他对 PingCAP 的整个印象更好了，决赛前就想不论 TiDB Visual Plan 这个项目能不能拿奖，在比赛后都会尽力把它给融入到 TiDB 的 Dashboard 里面，把技术迁移的事情做完。\n\n### 挑战\n\nTiDB Dashboard 是 TiDB 自 4.0 版本起提供的图形化界面，用于监控及诊断 TiDB 集群。团队刚开始想把 TiDB Visual Plan 的可视化融入到 Dashboard 里面，但在前端选型后，发现一个很大的问题，就是两个技术栈是不兼容的，整个迁移的成本会非常大。由于团队成员日常工作就很忙，当时留给前端开发这边的时间大概只有一两天，但如果迁移至少得一个星期才能完成。最后团队就讨论决定与其把工作重心放在融入到 Dashboard 上，还不如换个方向，对执行计划的可视化本身进行优化，比如跑最复杂的测试 SQL、集成 index recommendation 等。从最后的结果来看，当时做这样一个决策还是相当成功的。\n\n### 趣事\n\n初赛的时候，Demo 演示的那段视频只有队长 Yves 能听得到声音，其他人都听不到声音，而团队成员还非常淡定地坐在那里没有打断（答辩时 Yves 戴着降噪耳机，答辩完之后没拔耳机就信心满满地给评委放 demo 视频直到结束——如下图），以至于让线上的评委们看了一段无声版的 Demo（远在深圳的 92hacker 还以为这个视频本来就是无声的），但其实视频是有精心准备的语音讲解。不过没有讲解大家也能看懂，也验证了团队的产品哲学，大道至简。\n![06.webp](https://img1.www.pingcap.com/prod/06_ca2c9829c6.webp)\n\n## 未来工作展望\n\n除了获得三等奖，对于被评为 “用户之选” 奖，TiVP 团队觉得非常意外。在做这个项目的时候，团队并不是从一个很大的 scope 着手，而是发现了目前执行计划存在的痛点。在解决执行计划可视化的同时，又发现有很多可以改进的地方，包括易用性、交互性，以及未来的一些智能化等。整个项目的思路就是从用户的角度去想问题，切中用户的痛点，团队猜测也许这是打动 TiDB 用户代表评委的一个重要原因。\n\n尽管 Hackathon 2021 比赛已经落幕，但 TiVP 团队还在为 TiDB Visual Plan 的技术栈迁移到 Dashboard 而持续努力，推动 TiDB 尽快融入这个新功能，让 DBA 从满屏密密麻麻的执行计划代码中得到解放。\n\n目前 TiDB Visual Plan 主要是做执行计划的可视化，未来不仅希望进一步提升内核的可诊断性：如优化器优化流程的可视化；还希望能在深度和广度兼容上做更多的探索：譬如赋予优化器以 whatif 的思考能力，提供给用户一键调优的极佳体验；再譬如通过定义接口协议，把 SQL 调优工具从 TiDB 拓展到 MySQL、PostgreSQL、Oracle 以及 SQL Server 等，做成一个更加通用的云服务版本。正如 TiVP 团队的宣言 “把复杂交给我们，把简单还给你”，云化后兼具易用性、扩展性和智能化的 SQL 执行计划可视化服务会是星辰大海。\n\n> 延展阅读：点击查看更多 [TiDB Hackathon 2021 优秀项目分享](https://pingcap.com/zh/blog/?tag=TiDB%20Hackathon%202021)","date":"2022-01-26","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"tidb-visual-plan","file":null,"relatedBlogs":[]},{"id":"Blogs_336","title":"TiDB Hackathon 2021 — 极简实现 TiDB 冷热数据分层存储 | He3 团队访谈","tags":["TiDB Hackathon 2021"],"category":{"name":"社区动态"},"summary":"本篇文章将介绍 TiDB Hackathon 2021 He3 团队赛前幕后的精彩故事。","body":"> 参加 Hackathon 可以接触到内核、工具、生态各个领域中志同道合的小伙伴，通过他们的项目学习到非常好的创意。大家的想法都很奇妙，充满了创新力，在平时的研发过程中，很少能接触到这些，Hackathon 能够帮助我们打开思维，让我们知道原来 TiDB 还可以这么玩。\n> <p align=\"right\">—— He3 团队</p>  \n\n![一等奖 He3 .mp4](https://img1.www.pingcap.com/prod/He3_8e3d4cff96.mp4)\n\nTiDB 在使用过程中，随着用户数据量的持续增长，存储成本在数据库总成本中的占比将会越来越高。如何有效降低数据库存储成本摆在了许多用户面前。\n\n在众多解决方案中，有一种方法是将冷热数据实现分层存储。在绝大部分场景中，数据其实都可以分为 “冷数据” 和 “热数据”。数据划分的原则，可以根据时间远近、热点/非热点用户等等。用户通常只访问一段时间之内的数据，例如近一周或一个月。如果数据不做划分，必然会导致一定程度上的性能、成本损耗。\n\n**在刚刚收官的 TiDB Hackathon 2021 中， He3 团队就选择了冷热数据分层存储来降低 TiDB 的存储成本**。他们在设计中将热数据存放在 TiKV 上，将查询和分析几率比较少的冷数据存放到便宜通用的云存储 S3，同时使 S3 存储引擎支持 TiDB 部分算子下推，实现 TiDB 基于 S3 冷数据的分析查询。项目获得了评委的一致好评，力夺本届赛事的一等奖。\n\n\n> 这个项目为后面 TiDB 与 S3 的整合打下不错的基础，在这次 Hackathon 验证了可行性。它的原理其实很简单，将冷的数据放到 S3，将算子尽量下推到 S3，通过 S3 原生的 select 功能加速查询。当然，如果数据已经在 S3，还可以通过 Cloud 上其他的服务，譬如 Athena， 来做更多的查询聚合操作，加速查询。这次大家都是在通过 partition 做文章，毕竟根据时间片来分的 partition 是非常常用的一种操作。我们内部现在也在通过 LSM 做一些跟 S3 整合的研究，我还是很期待这些都能在今年看到不少的成果产出。譬如 TiDB Cloud dev tier 集群就可以完全用这套机制来验证。  \n> <p align=\"right\">—— 评委唐刘点评</p>\n\n\n## 为什么选择冷热数据分层存储这个方向？\n\nHe3 团队的队长薛港，队员时丕显、沈政，都是来自移动云数据库团队的研发工程师，三人平时的工作就是从事云数据库服务的开发，降低用户在云上使用数据库的成本是他们一直追求的目标。\n\n在去年 7 月份的 Hacking Camp 中，He3 就曾基于 TiDB 实现了提供 Serverlessdb 服务的 Serverlessdb for HTAP 项目。用户在使用 TiDB 时可以按使用量付费，不用再像传统 RDS 需要包年包月，大大**降低了用户使用 TiDB 的成本**。该项目也因此获得了 Hacking Camp 优秀毕业生和最佳应用奖。\n\n随着产品在移动云上的落地，很多用户在使用了一段时间后发现随着数据量的增加，存储成本越来越高。薛港解释道，在公有云上，块存储收费比 S3 对象存储要高很多，用户部分场景的数据其实很多是冷数据，完全可以存放在 S3 上。于是在去年 12 月份时，他们就开始思考如何降低 TiDB 的存储成本。恰好这时 TiDB Hackathon 2021 启动了，薛港和时丕显、沈政一商量，就决定将冷热数据分层存储作为今年的比赛项目。在答辩时，他们专门用了一页 PPT 分析了运用该项目后的成本变化：\n\n![01.webp](https://img1.www.pingcap.com/prod/01_6148d56be8.webp)\n\n![02.webp](https://img1.www.pingcap.com/prod/02_f5b77dcb59.webp)\n\n项目方向定了，接下来就该报名了。队长薛港在看电视的时候对氦 -3 这种元素产生了兴趣，经过了解，发现它可以用作核聚变燃料，比现有的核燃料能量更大，并且只有很少的放射性，是一种清洁高效安全的发电燃料。这种特性和他们对分布式云数据库的期望完全一致 —— 安全、高性能、易用、价格便宜，于是 He3 便成了队名。\n\n在接下来不到一个月的时间中，薛港作为队长负责整体需求的确认、架构设计、方案验证以及具体框架的开发。其他队员主要负责功能开发，时丕显负责算子下推与数据类型支持，沈政重点在性能优化以及 TPC-H 测试。\n\n## 该项目解决了什么问题？\n\nHe3 开发的 TiDB 冷热数据分层存储项目，能够以极简的方式实现冷热数据分离：\n![03.webp](https://img1.www.pingcap.com/prod/03_bbb9eea5d2.webp)\n\n**针对普通表**：实现 insert into select 的方式完成冷热数据分离：\n\n- 支持创建 S3 外部表；\n- 支持通过 insert into s3_table select from tikv_table where ... ，把 TiKV 内部表的数据转储到 S3 对象存储上；\n- 支持通过 insert into tikv_table select from s3_table where ... ，把 S3 外部表的数据转储到 TiKV 内部表。\n\n**针对分区表**：自动完成分片表转化成 S3 外部表，保留主表和 S3 外部表的主从关系。\n\n支持通过 Alter 分区表操作，把 TiKV 内部分区表的数据自动转储到对应的 S3 外部表中，自动完成以下几件事：\n\n- 内部 TiKV 分区表数据转存到 S3 对象存储中；\n- 更改分区表元数据，把 TiKV 内部分区表转化成 S3 外部表，核心要点保留 S3 外部表和主表的分区关系；\n- 删除 TiKV 内部分区表数据。\n\n转换后 S3 外部分区表对用户完全透明，对用户来说，S3 外部表就是主表的一个分片表。例如针对主表的查询结果包含部分 TiKV 内部分片表以及部分 S3 外部表对应的分片表数据，那么返回的结果就会来自两部分：TiKV 内部分片表，以及 S3 外部表。\n\n保证用户使用 S3 外部表和 TiKV 内部表没有任何区别：\n\n- S3 外部表支持所有的数据类型；\n- S3 外部表支持所有的算子；\n- 优化 S3 外部表操作性能在用户可接受的范围内。\n\n通过支持谓词(逻辑运算、比较运算、数值运算），聚合函数、Limit 等算子下推到 S3 节点，利用 S3 的计算能力提升查询性能。\n\n为了达到期望所有效果，He3 在此次 Hackathon 中开发修改了 TiDB 一些模块：\n\n### SQL Parser 模块、系统表模块\n\n- 增加一个新的系统表，用于保存 S3 元数据， 每一条记录对应一个 S3 存储元数据：包含 S3 的 endpoint, access key, secret key， s3 bucket。insert into mysql.serverobject values(\"s3object\",\"http://192.168.117.220:9000\",\"minioadmin\", \"minioadmin\",\"s3bucket\")；\n- 支持创建外部表，相比普通表增加了 s3option 选型，对应 S3 元数据对象，外部表对应 S3 的存储路径：Bucketname/DBName/TableName create table s3_table(id1 int8,id2 char(30)) s3options s3object；\n- 支持分片表自动转换成 S3 外部表\n\nAlter table employees alter partition employees_01 s3options s3object\n\n### 执行器模块\n\n- 能够区分操作表是否是 S3 外部表，如果是外部表，写入时，数据以 256M 为粒度保存到 S3 的一个对象中 , 当查询 S3 外部表时，S3 对象会被以流式的方式装配到 chunk 中，以支持上层算子操作；\n- 支持算子下推到 S3 节点，利用 S3 节点的计算能力加速 S3 外部表的性能；\n- S3 外部表支持所有的数据类型，存储在 S3 的数据按 S3 外部表的 schema 对应的数据类型保存到 chunk 里，相关列都会基于数据类型编码；\n- 支持 Alter 实现内部分片表数据自动转储到 S3 外部表中，同时保留主表和 S3 外部表的主从关系不变。\n\n### 优化器模块\n\n少量无法下推 S3 的算子，He3 修改了优化器阻止这部分算子下推。当前不支持的算子，主要就是包含 TopN 算子。\n\n## 来自性能测试的挑战\n\nHe3 最初设定的目标有两个：一是希望数据能够以比较简单的方式直接实现冷热数据分离；二是希望冷数据分离到 S3 后，它的查询性能能够在合理的时间范围内。所以一开始就把跑通 TPC-H 作为目标。\n\n项目的冷热数据分离功能很快就完成了开发，但是接下来他们遇到了一个最大的问题——性能总是无法达标。一开始的方案设计是将全部数据都读取到 TiDB 上集中处理，但在测试中发现即使只有 10GB 的数据，TPC-H 也跑不出来。三名队员通过讨论、调研、分析，发现 S3 其实也具备一定的计算能力，是否可以把部分计算下推到 S3 ，让 S3 和 TiKV 一样能够承载部分计算？\n\n改变方案后通过几个场景算子下推，He3 发现性能提升非常明显，在之后的开发中就将能下推的算子全部下推，项目的整个性能优化每天都会以 20% 的幅度在提升。最终在比赛日上，他们跑通了整个 TPC-H 测试。\n\n![04.webp](https://img1.www.pingcap.com/prod/04_86dc44f336.webp)\n<center>He3 在 Hackathon 中的 TPC-H 测试成绩</center>\n\n![He3-薛港-Demo.mp4](https://img1.www.pingcap.com/prod/He3_Demo_31ab8387b5.mp4)\n\n此次 Hackathon 中，其实还有另一支赛队 Interstellar 也选择了分层存储，这也给 He3 队员们留下了一个有趣的画面：在 Interstellar 开始答辩时，He3 以为是自己在投屏，手忙脚乱地到处找关闭投屏按钮，直到对方开始答辩了，他们才意识到原来是两个队伍的题目撞衫了。\n\n## 本次参赛的心路历程\n\nHe3 队员们其实在去年也参加了 TiDB Hackathon，因为刚接触 TiDB ，并没有碰内核。当时心中就埋下一个想法，下次参赛一定要做够硬的项目。这也是薛港在毕业后就给自己树立的目标 —— **做数据库内核**，并认为这是一件很酷的事情。于是在今年比赛中， He3 选择了最硬核的赛道 —— 内核组。\n\n过去一年的工作对他们帮助非常大，由于三人平时的工作和 TiDB 结合非常多，在碰到问题的时候就会去想有什么解决方案，这个过程中很容易产生各种好的 idea。例如这次如何降低 TiDB 存储成本的问题，他们当时就想出了至少三种方案：第一种是将 TiDB 底层的编码方式做一些改变，让 TiDB 的整个压缩比能够再下降 50% - 60%；第二种也是一种冷热数据分离方案，将 LSM-tree 和 S3 集成；第三种就是现在的冷热数据存储分层方案。但前两种方案在 Hackathon 如此短的周期内很难完成，于是他们就采用了第三种方案。\n\n未来， He3 还会从三个方向将该项目持续演进、迭代：\n\n- 通过新的编码方式以及加速算法，降低数据在 S3 的存储容量，基于本次比赛中实现的效果再降低 50% 的存储容量；\n- 持续优化 TiDB 对接 S3 的存储差异性能，在这次比赛的后期，这块性能每天都有 20% 的性能提升，He3 认为这里其实还有很大的提升空间；\n- 进一步简化用户的冷热数据分离方式。对这次项目的最终实现， He3 其实还有一些遗憾，一开始设计的时候他们想过现在冷热数据分离还需要 DBA 来做一些操作，如果能将这个工作进一步实现自动化操作，就可以让冷热数据分离应用性再上一个台阶，不过由于时间比较有限的原因没能实现。\n\n此外，除了项目本身继续完善外，He3 还希望在迭代到一定程度后就将整个产品的代码提交给社区，用开源的方式回馈社区，大家一起共创。  \n\n> 延展阅读：点击查看更多 [TiDB Hackathon 2021 优秀项目分享](https://pingcap.com/zh/blog/?tag=TiDB%20Hackathon%202021)","date":"2022-01-24","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"implementation-of-cold-and-hot-data-layered-storage-in-tidb","file":null,"relatedBlogs":[]},{"id":"Blogs_337","title":"TiDB Hackathon 2021 — 为数据库性能调优插上 AI 的翅膀 | 调优测试框架 Matrix 团队访谈","tags":["TiDB Hackathon 2021"],"category":{"name":"社区动态"},"summary":"本篇文章将介绍 TiDB Hackathon 2021 Matrix 团队赛前幕后的精彩故事。","body":"![明势资本赞助最佳市场潜力奖 Matrix.mp4](https://img1.www.pingcap.com/prod/Matrix_0a800d3a75.mp4)\n\n在刚刚结束 TiDB Hackathon 2021 赛事中，Matrix 赛队的作品 Tenseigan，是针对 TiDB 的一个分布式数据库的调优测试框架，该工具能够提供：自动调参、参数影响度评估等功能，集成了多种 workload。由于项目的创新性和可扩展性，摘得了“最佳校园奖”和“明势资本特别赞助最佳市场潜力奖”。\n\n![01.webp](https://img1.www.pingcap.com/prod/01_31fedf1977.webp)\n<center>陈书宁代表 Matrix 赛队在现场领奖</center>\n\n本篇文章将通过 Matrix 团队与明势资本执行董事徐之浩的对话，揭秘团队赛前幕后的精彩故事，也希望给开发者们未来基于 TiDB 开发自己的应用和项目带来一些启示。\n\n## Matrix 队名的由来\n\n**童剑**：如果把 TiDB 看成是黑客帝国的一个矩阵，我们的项目 Tenseigan 就像是黑客帝国的男主角 Neo，本身有很强的学习能力，可以自我进化，最终还可以成为救世主一样的存在。所以取了 Matrix 这个名字。\n\n## 项目的灵感来源\n\n**丁晨**：这个项目的灵感来源于 2017 年 SIGMOD 顶会的一篇 paper，也就是 OtterTune 框架。我们做这个项目的初衷是想看看 OtterTune 在 TiDB 上的表现，能否落地到生产环境，去解决实际的问题，以及 OtterTune 框架本身还存在哪些问题，对于分布式的场景，会不会有新的研究点产生。\n![02.webp](https://img1.www.pingcap.com/prod/02_b3ca4c38c5.webp)\n<center>Tenseigan：一个适配 TiDB 的自动化调优测试框架</center>\n\n## 投资人评委眼中的项目价值\n\nMatrix 团队的精彩创意也给明势资本执行董事徐之浩留下了深刻印象，徐之浩在加入投资行业之前，也有过近 10 年研发工作经历，对这类 Infra 的项目非常感兴趣。\n![03.webp](https://img1.www.pingcap.com/prod/03_be9394731b.webp)\n<center>明势资本执行董事徐之浩在 Hackathon 颁奖现场</center>\n\n**徐之浩**：选择这个队伍获得最佳市场潜力奖，主要是因为这个项目有很强的扩展性，另一方面也比较有创新性。之前大家对数据库的优化更多停留在内核和优化器、执行器或者架构部分，但从用户的视角来看，通过一些配置和参数的调整就可以获得很好的性能提升。大家都聚焦在内核的优化上，没有太多人来关注调参这部分，所以这个方向还是比较有创新性的。\n\n在技术栈的选择上，选择用 AI 代替人来选择最优的参数也是比较创新的。最近 Google 也在提用 AI 本身去优化 AI 的训练框架，这本质上也是一种调参，是 ROI 很高的一个研究方向。如果能作为产品化的插件用在 TiDB 上的话，对 TiDB 的性能是如虎添翼的。这样被训练完之后的 AI 也就像一个运维老师傅一样，可以更高效地给出更好的参数建议，是有未来机器替代人工的现实意义的。\n\n## 作为学生参赛的特殊体验\n\nMatrix 赛队可以说是华中科技大学的代表队，队长丁晨在华中科技大学读博二，研究方向是基于新硬件的键值存储系统；熊逸钦是丁晨在同一个实验室的学弟，在读研一；童剑和陈书宁也都毕业于华中科技大学，目前在 PingCAP 做研发工程师。\n\n**丁晨**：作为学生参赛，最大的感受就是 Hackathon 是一个高强度、沉浸式的项目体验，这种机会在学校里面是比较少的。在学校里做事情通常比较慢，也没有 Deadline，像这种两天内就需要写一个小项目，对于学生能力的挑战还是比较大的。此外，借助这个机会接触工业界实际的问题，对于我们做研究还是很有帮助的。因为我们做研究很多是从逻辑出发，如果了解到工业中的实际问题，就可以试着去解决实际遇到的问题。\n\n**熊逸钦**：这是我第一次参加 Hackathon，作为学生或者第一次参赛的选手来说，Hackathon 这种形式对我来说是前所未有的，而且很有吸引力。因为在短短两天的时间内，我全身心地投入到项目中去，给我个人带来的提升也是非常大的。\n\n## 团队协作共同攻克技术困难\n\n**丁晨**：前期主要是我跟逸钦负责集群搭建和框架部署，以及一些 TiDB 适配的工作。后期书宁和童剑主要是把生产环境的一些 Workload 给构造出来，然后让调参的效果凸显出来。我们分别构造了一个 TiDB、PD、TiKV 的 Case，后来我就去写答辩的 PPT 和 Demo 了。\n![04.webp](https://img1.www.pingcap.com/prod/04_11c7d51e74.webp)\n<center>陈书宁和童剑在 Hackathon 广州现场</center>\n\n**Q：在比赛过程中你们遇到过什么比较大的技术困难？是如何解决的？距离真正生产可用还差多远？**\n\n**丁晨**：最开始，我们针对典型的 TPCC 的负载做性能测试的时候，发现 OtterTune 对于调参的效果不太明显。因为 TiDB 对于这种标准的测试，默认配置参数已经优化得比较好了。后来我们就去尝试构造一些在真实生产环境中遇到过的、有瓶颈的 Case。只有在有瓶颈的 Case 下面，调参的效果才能够比较好的体现出来。这是我们遇到的一个技术难点，就是如何构造一个真实的环境，把调参的效果给展示出来是我们遇到的一个问题。\n\n在框架的易用性方面的话，其实 OtterTune 的框架还是不太好用的，我们这个项目也是做了很多很多个脚本，就像是跑了一个脚本集。如果要让它更加易用的话，可以在框架上做一些改进，比如可以把脚本放在网页上，一键运行，让运维和研发更加方便地使用。未来如果能够把 OtterTune 跟 TiDB Cloud 结合起来，在云上可以给运维提供更好的环境，而把复杂性隐藏起来，应该是一个更有想象力的场景，这也是未来我们这个项目希望去扩展的地方。\n\n## 成本问题 & 由于时间原因未完成的遗憾\n\n**徐之浩**：我还是比较好奇，你们有没有算过要构建这么一个训练的集群，需要花费多少成本？如果真要把它做成生产可用的产品的话，我理解还是需要有很多数据准备的，在这种情况下，如何保证训练成本依然可控呢？\n\n**丁晨**：成本这个问题是一个关键问题，我们在做的时候其实并没有太考虑这个问题。我们跑的数据也就是几百个点的规模，后续如果要用在生产环境的话，可能需要一个专门的调参集群，去做 AI 模型的训练，把各种各样的用户数据收集到这个集群里面，让 AI 模型去学习不同业务的 Workload，以及不同硬件配置下的经验。这个经验是可以复用的，也可以提高数据的使用效率，当这个训练足够多以后，成本是可以降低的。\n\n**Q：这次 Hackathon 的时间有限，你们在比赛过程中还有什么遗憾吗？**\n\n**丁晨**：目前我们的项目只能给出一个最优的参数。但没办法解释这个参数为什么最优，就是说我们的 AI 还是缺乏可解释性的，我们还想做一个可视化的模块，直观地展示性能和最优配置之间的关系，从而帮助运维和研发去分析参数背后的原因。但因为时间原因，可视化这里还没做得很直观，只是做了一个列表。另外还有一些 Case 的测试结果不太符合预期，这一点跟 Workload 还比较有关联，后续如何让框架整合更多 Workload，让不同 Workload 之间的调参经验可以相互复用是一个需要考虑的问题。\n\n**熊逸钦**：因为时间关系，我们测试的覆盖度还是不太够，包括测试数量和测试参数都不是太完善。\n\n**童剑**：其实一些有经验的 DBA，对于参数应该怎么调整是有自己的经验的。但他们通常只能给出一个方向性的建议。我们想做的实际上是把这种关系给具体化，能够知道参数的变化关系，从而快速定位到最优参数的位置。这样能加速收敛这个过程。\n\n**陈书宁**：我这边主要有 2 个遗憾，一个是因为疫情关系，2 位队友没有办法来到现场一起 Coding。另外因为这次参赛者比较多，预赛和决赛分开，没有办法保留完整的 24 小时持续编程的时间。其实那种连续 24 小时不间断 coding 的体验是很吸引人的。\n\n## 评委眼中的 TiDB Hackathon\n\n**徐之浩**：这是我第一次担任 Hackathon 的评委。TiDB Hackathon 给我的感受是特别硬核，之前我还在做程序员的时候参加过公司组织的 Hackathon，但感觉没有这次这么硬核。这次有 AI 类的项目，也有直接在 TiKV 上面做图数据库之类的项目，硬核程度完全超乎我的想象。\n![05.webp](https://img1.www.pingcap.com/prod/05_b4cc880544.webp)\n<center>明势资本执行董事徐之浩在 Hackathon 现场参与评审</center>\n\n这次 Hackathon 对于 TiDB 也是非常有价值的，有很多项目离进入 TiDB 产品已经很近了，实用性方面也是非常棒的。而且这个过程中大家开了很多脑洞，产生了很多对产品迭代和产品周边非常有价值的想法。所以 Hackathon 也可以看作是社区智慧的年度大爆发，在其中能非常切实地感受到社区小伙伴的创造力和潜力。\n\n从活动组织上来看，活动早期的宣传造势，以及当时有个社区粉丝做得很炫酷的 “找队友” 的短视频，都让我印象深刻。另外决赛环节中，一些没有进入 20 强，但在单个方向上表现比较突出的项目也有机会能参与独立奖项的角逐，展示自己的项目，这一点还是比较贴心的。唯一比较考验的就是我们这些老评委的体力，整个答辩的时长还是比较长的。\n\n## 展望与期待\n\n**Q：徐老师作为投资人，您对该项目有哪些商业化的建议吗？**\n\n**徐之浩**：我的建议还蛮多的，这个项目离一个可以商业化的产品还有很长的路要走。第一，我们可以把产品做得更稳定一些，不能在某些 workload 中表现很好，在其他 workload 中没有效果。因为这个调参是针对数据库，或者其他的 Infra，对于企业都是非常核心的部分，如果表现不稳定是很难商业化的。\n\n第二就是成本问题，需要把 AI 的算法和人的经验结合起来，比如把一些不相关的因素通过人的经验先排掉，这样能让 AI 更快地趋近好的效果，也能节省成本。\n\n第三，建议可以先针对某一款软件的场景打穿打透。这个过程中就需要跟软件的原厂比如 PingCAP，保持比较紧密的合作，比如获得更多真实环境中的数据等。另外考虑到商业模式，调参也不要做成一锤子买卖，尽量做成一个持续动态的调参建议，会让我们的商业模式更加有想象力。\n\n**Q：你们的项目这次获得了明势资本特别赞助的最佳市场潜力奖和校园团队奖，未来希望继续把这个项目继续下去吗？**\n\n**丁晨**：我们是希望继续完善的，一方面是往云上做适配，另外希望整合更多的功能，比如可视化的展示和 AI 的因果推理等。还有前面徐总提到的动态负载的调优，同时兼顾收益和成本的关系。再就是优化框架，也需要社区实际生产环境中的数据。\n\n**Q：期待明年的 TiDB Hackathon 有哪些改进？**\n\n**丁晨、熊逸钦**：可以考虑吸引更多高校的学生参与进来，加强在校园圈的宣传力度。\n\n**童剑**：首先，学生对 TiDB 和工程实现没有那么熟悉。所以希望可以给校园群体设立独立赛道，独立评奖。另外，对于初赛被淘汰的队员，决赛的参与度不高，可以多增加一些展示和互动的环节，让初赛选手也能持续关注决赛。\n\n**徐之浩**：希望赛前提前给评委一些项目简介，帮助评委更好地理解项目。另外，现场评审的强度挺高的，大脑信息已经过载，有点审美疲劳了，中间希望有更多休息。也希望在赛前看到前一年 Hackathon 项目的状态和落地情况等，这对选手和评委都是一种鼓舞。  \n\n> 延展阅读：点击查看更多 [TiDB Hackathon 2021 优秀项目分享](https://pingcap.com/zh/blog/?tag=TiDB%20Hackathon%202021)","date":"2022-01-21","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"ai-in-database-performance-tuning","file":null,"relatedBlogs":[]},{"id":"Blogs_338","title":"TiDB Hackathon 2021 — 只有天空才是你的极限，我们热爱探索的过程并沉浸其中丨图数据库 TiMatch 团队访谈","tags":["TiDB Hackathon 2021"],"category":{"name":"社区动态"},"summary":"本篇文章将介绍 TiDB Hackathon 2021 图数据库 TiMatch 团队赛前幕后的精彩故事。","body":"<center>只有天空才是你的极限，我们热爱探索的过程并沉浸其中</center>\n\n> Hackathon 本身带给我们的是一次全新的探索，并不只是一队人有一个明确的目标，花几天时间写代码，那其实是很无聊的。探索的本身让我们发现，越探索越能找到更新、更好、更优雅的解决办法，我们热爱这个探索的过程并沉浸其中…… \n> <p align=\"right\">—— TiMatch 赛队</p>\n\n![01.webp](https://img1.www.pingcap.com/prod/01_8d674842bf.webp)\n<center>战队成员之一柏佳辰是一个爱画画、爱摩托车、喜欢读《理想国》，建筑学出身的程序员。</center>\n\n在 TiDB Hackathon 2020 赛事中，[TiGraph](https://pingcap.com/zh/blog/when-tidb-meet-graph-database) 项目在 TiDB 中实现了一套新的 Key-Value 编码来引入图模式，处理传统关系型数据库难以覆盖的图数据分析场景，实现了 TiDB 在四度人脉的计算性能大幅提升，夺得了二等奖。\n\n在刚刚收官的 TiDB Hackathon 2021 赛事中，TiMatch 在去年项目的基础上做了一次进化升级，构建了基于 TiDB 和 TiKV 的语法完备的分布式图数据库，探索出一条在 TiDB 之上构建一个成熟且易于使用的图数据库的路径。项目获得了现场评委的一致肯定，拿下本届赛事的二等奖。\n\n> TiMatch - 语法完备的分布式图数据库，去年 TiGraph 已经让大家惊艳，今年 TiMatch 更让人期待了。这次易用性更好，而且对于老集群也能直接升级使用。因为 TiMatch 只是内部建立了一套 graph index，然后通过 TiDB 分布式事务机制，跟原先关系表的数据统一更新。语法上面，借鉴了 Oracle graph 的语法，所以已经是关系完备的了，不过我觉得后面的挑战在于性能上面，希望后续这块能给大家展示相关的数据。\n> <p align=\"right\">——评委唐刘</p> \n\n> 点评非常惊艳，借助 TiKV 的扩展能力+ TiFlash 的分析能力，想象空间很大，希望能尽快 GA！\n> <p align=\"right\">——评委冯光普</p>\n\n## 为什么选择图数据库这个方向？\n\n图技术已成为现代数据和分析能力的基础，能够在不同的数据资产中发现人、地点、事物、事件和位置之间的关系。依靠图技术可以快速回答以往需要了解情况并理解多个实体之间的联系和优势之后才能回答的复杂业务问题。\n\n图数据库一直是业界的热门话题。它具有用于语义查询的图形结构，使用顶点、边和属性来表示和存储数据，支持对在关系数据库系统中难以建模的复杂层次结构进行简单快速的检索，优雅地解决了传统关系数据库在针对复杂关系或多表 JOIN 情况运行结果时经常出现的性能或故障问题。我们身边有很多图应用的案例，比如 Google PageRank 算法；LinkedIn 用图管理社交关系，实现好友推荐；Amazon 用图实现实时的商品推荐；银行用图做风控，实现反欺诈和反洗钱等等。\n\n![02.webp](https://img1.www.pingcap.com/prod/02_1b177408bf.webp)\n\n从 DB Engine 的统计数据可以看到，在全球范围内，从 2014 年开始，图数据库的受欢迎程度一直呈现迅猛的上升态势，超越了其他各种类型的数据库。据 Gartner 预测，到 2025 年图技术在数据和分析创新中的占比将从 2021 年的 10% 上升到 80%，该技术将促进整个企业机构的快速决策。\n\n## 从去年的 TiGraph 到 TiMatch 项目实现了哪些提升？\n\n去年的 TiGraph 项目留下了一些遗憾，比如图查询语言不完备，没有接入 TiKV 存储引擎等。这次 Hackathon 赛事中 TiMatch 的任务就是基于 TiDB 和 TiKV 设计语法完备的分布式图数据库雏形，继续探索在 TiDB 之上构建一个成熟且易于使用的图数据库的路径，TiMatch 实现了三大方面的提升。\n\n![03.webp](https://img1.www.pingcap.com/prod/03_1e00e541bb.webp)\n\n### 提升语法的完备性，语言上面引入了 Oracle PGQL 语法\n\n通过在 WHERE 子句后引入 TRAVERSE 子句来进行图遍历，主要是探索看看是否能进行有效整合，是否可以无缝算子复用，语法是否足够简单，子查询是否可以友好地相互嵌套。虽然最终是达到了验证的目的，但是由于数据来源需要依赖底层的 SELECTION 算子，所以进行图计算时不能进行多个边匹配，在子图匹配和最短路径等其他图算法场景中难以构造对应的查询，本质上是语法的完备性存在问题。\n\n好在 2021 年 Oracle 的 PGQL 也在对图查询语言和 SQL 语言的兼容结合进行探索，并且发布了 1.0 的规范。我们直接参考了 PGQL 语法，在 TiDB 中实现了完整的 PGQL parser 提升了查询的完备性，在语法上支持图遍历、子图匹配、TopK、最短路径等图算法，算法的具体实现除了图遍历，今年也实现了最短路径查询。\n\n### 降低系统复杂度和学习成本\n\n简化和完备性的提升直觉上是相悖的，这次的方案在读取路径和写入路径上区别对待，读取路径尝试通过 PGQL 图查询语言来提升查询的完备性，需要引入新的语法规则。在写入路径上，探索出一个全新的方案，去年的方案我们引入了很多新的语法，比如：\n\n- CREATE EDGE/TAG\n- SHOW EDGES/TAGS\n- SHOW CREATE TAG/EDGE\n- DROP TAG/EDGE\n- ALTER TAG/EDGE\n- ...\n\n这些语法对已有的应用程序和 ORM 生态都会有比较大的兼容性冲击，需要进行大量的应用修改和生态兼容。\n\n今年我们在不停的讨论和尝试中找出了一个全新的方式，尽量少地侵入用户层接口，完全在数据库内部完成兼容，将外部兼容问题转换为数据库内部图模式的兼容性问题，局部看工作量变大了，但是更加符合全局最优解。\n\n1. 顶点的 DDL 语法完全不变化。\n1. 变的语法加入了 SOURCE/DESTINATION KEY Column Option，写法和 FOREIGN KEY 是一样的，所以对于开发者和 DBA 都不会有新的学习负担，MySQL 的 Column Option 有接近 20 个，所以新增的只有 Column Option 的 2/20，而 Column Option 的作用域及其小，相关去年的新增几十个语句级别的语法，今年可以说是相当轻量。\n\n是否有可能完全消除新语法？\n是可以的，比如使用以下的方式：\n\n```\nCREATE TABLE (\n  a bigint /*T! SOURCE KEY REFERENCES students */,\n  b bigint /*T! DESTINATION KEY REFERENCES students */\n)\n```\n\n使用注释的方式可以完全消除对上下游的影响，但是注释在语法解析阶段不容易很早就通过 parser 发现错误，并且很多人会忽略注释，所以这里没有完全追求 100% 的兼容性。\n\n**自动构建图拓扑**  \n\n通过引入 SOURCE/DESTINATION KEY 之后，数据库内部就有足够的信息自动构建图拓扑，其实从图数据库的角度来说，主要是完成三部分工作：\n\n- 图数据存储\n- 图拓扑的维护\n- 图算 fan\n\n图数据（顶点）的存储和传统数据存储并不需要引入过去的差异性，大多是内部存储细节和 Key-Value 设计的差别，如何维护图拓扑和已有数据，如何新增图拓扑是一个新的问题，在本次 Hackathon 我们提出了一个新的方案，可以对已有数据通过 ALTER 语句和 SOURCE/DESTINATION KEY 信息自动构建已有数据的图拓扑，免去任何的数据迁移和业务改造过程。\n\n### 从单机存储 unistore 到 TiKV+TiFlash，提升数据集支持规模\n\nHackathon 2020 由于时间所限使用了用于跑单元测试的 unistore，而今年引入 TiKV 存储引擎，运算性能也极大的提升，在 Demo 演示中可以看到，100 万点的单源 6 度人脉查询只需要 200 毫秒，相比去年在 unistore 上 10 万数据需要 6 秒来说，性能提升极为明显。未来还可以引入 TiFlash，利用 TiFlash 的 MPP 能力进行大规模图计算。\n\n## 通过两届 Hackathon 的迭代在 TiDB 上实现图数据库 TiMatch 探索出了一条怎样的路径？\n\n- 首先是兼容 TiDB 已有的功能、已有的数据和已有的生态（DM/CDC/Lightning/ORM/ 等）\n- 考虑自适应图 DDL 和已有数据自动兼容，从而自动构建图拓扑\n- 支持 TiKV 存储引擎，进行完整的 Parser 实现\n- 完善图查询：遍历、路径过滤、最短路径、谓词下推、Coprocessor 下推等\n- 事务、索引、嵌套子查询等方面的考量\n\n## 在 Hackathon 上获得二等奖的好成绩最主要的原因是什么？\n\n最主要的原因是这个项目站在了“三层”巨人的肩膀上面，才能呈现在大家的面前\n\n一层：思考上延续了 TiGraph，实现和语法上是一个垫付，语法上完备了许多  \n\n二层：在 TiDB 和 TiKV 既有框架上进行实现，扩展图数据库，拓展 TiDB 的场景  \n\n三层：引入了全新的语法，完成对图数据库查询的万备汛，从 Oracle PGQL 延伸过来，原版的语言有些地方比较啰嗦，不是很考究，对其进行了一定的修改，变得更加优雅\n\n其次，团队的明确分工，队员之间的彼此信任和无缝协作\n- 龙恒、夏雨杰、刘东坡：着重实现 TiDB 侧的语法分析、AST、Parser、写入路径等\n- 柏佳辰：负责 TiKV 侧算子下推，并承担队宣的角色（制作宣传视频 + PRC PPT 等）\n\n## 作为一名北美的选手首次参加 TiDB Hackathon 有什么感受？\n\n柏佳辰，GitHub ID：JeepYiheihou\n\n哈佛硕士毕业，现就职于 AWS 温哥华，从事 ElasticCache 缓存数据库核心研发工作，利用假期参与了此次 Hackathon。整个 Hackathon 的过程对我来说是一次开心的体验。赛队全情投入，竞争特别激烈，赛制给足了时间让我们进行思考和创意，很多项目的完成度很高，也涌现了不少实用的项目。评委们提了不少犀利的问题，可以看出他们不止看到当下项目的闪光点，更会以长远的眼光去发掘这些项目在未来的方向和价值，我觉得评委们也是非常 enjoy 这个过程。\n\n**全栈程序员是怎么炼成的？**\n\n因为热爱。赛队的视频以及 RFC 的 PPT 都是出自柏佳辰之手。之前学过八年的建筑学，做精美的 PPT 是必修课，做视频也是自学的。这次赛队的宣传视频，借鉴了黑客帝国的主题，有一些帧用的是 processing 进行编程的可视化，用了 pathon 语言呈现了图、网格和网络。在转行做程序员之前，对编程很感兴趣，自学学编程，接触过使用可视化工具来制作视频，刚好这次用上了。\n\n> 不管做转行前或者转行后的任何事情，做职业决定的时候，要确定你是真的热爱它。热爱它，你就会对这件事情全神贯注，投入精力进去。转行做程序员大家都知道怎么去做准备，重要的不是第一步你怎么跨入这个行业，重要的是怎么把后面的每一步都做好。\n\n工作之外，柏佳辰的爱好非常广泛：喜欢画画，画了一系列油画棒的画；喜欢摩托车；喜欢去健身房锻炼身体；喜欢看书，最近在看哲学的书，比如《理想国》。最大的爱好还是写代码和看论文，这也是为什么转行做程序员，想要尝试一些有挑战的事情，去解决一些问题，并且享受解决问题的过程以及收到的反馈。  \n\n> 延展阅读：点击查看更多 [TiDB Hackathon 2021 优秀项目分享](https://pingcap.com/zh/blog/?tag=TiDB%20Hackathon%202021)","date":"2022-01-18","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"when-tidb-meet-graph-database-2","file":null,"relatedBlogs":[]},{"id":"Blogs_339","title":"“爆到天际线” - TiDB 2021 Hackathon 决赛不负责任点评","tags":["TiDB Hackathon 2021"],"category":{"name":"社区动态"},"summary":"本篇文章将介绍 TiDB Hackathon 2021 特邀评委，PingCAP 研发副总裁唐刘对决赛各项目的点评。","body":"![01.webp](https://img1.www.pingcap.com/prod/01_62a6110b87.webp)\n\nTiDB 2021 Hackathon 终于落下帷幕，最开始我还担心，今年 Hackathon 还有啥东西能出来，结果却大大超出我的预期，很多项目真的能用惊艳来形容，大家都在自嘲，说『内卷得太厉害』。作为评委，全程参与了预赛内核组以及决赛的答辩，还是有很多感触的，之前已经写了一篇[预赛的点评](https://zhuanlan.zhihu.com/p/454946684) ，这次也对决赛做一次不负责任的点评。\n\n决赛这次有 20 个项目，我大概分几个维度做一个统一介绍。\n\n## 性能/功能增强\n\n这次在 TiDB 内核上，做的不少性能提升功能真的很惊艳，因为我预赛点评的主要是内核组的东西，所以在这里简单进行一下汇总。\n\n### 增量 Analytic Table\n\n这个功能通过 Region Cache 统计信息的方式来加速全表的 analyze，在表越大的情况下，收益会越加明显。一方面加速了 analyze 的速度，另外一方面也能缓解 analyze 造成的大量 IO 和 CPU 开销，降低了系统的压力。不过这个实现有一个前提假设，就是大部分业务仍然是热点更新，或者增量写入为主。不过即使出现了大范围的更新，因为统计信息现在直接是放在 region cache 的，实际在 full analyze 的时候，效果也可能会比现在的实现要好。另外，我们后面可能还可以通过 TiFlash 进行 analyze 的操作，这样也会快很多。\n\n### TiExec\n\n这个项目虽然之前不是在内核赛道，但我觉得这玩意足够 hardcore 了。这也是我们在之前 PoC 过程中实际遇到的一个问题，我们发现调整一些内核的配置，或者 Go GC 的调整，性能就能提升。这次就是针对 iTBL-Cache-Miss 的问题进行优化。然后大家将 .text 这个 segment 映射到了 hugepage 上面，降低了 cache miss，提升了性能。本来评委还担心用了 hugepage 性能会不会下降，但实际这里并不是全局打开的 transparent hugepage，而只是单独的将某一段区间的数据 remap 到了 hugepage 上面。\n\n### TPC\n\n这个项目是我觉得最硬核的项目，我自己也给了非常高的分数，不过遗憾的是，可能太过于硬核，很多评委都不知道它在说什么（因为并不是所有评委都非常了解 TiDB 的内部机制），最终只得了三等奖，我个人觉得这个项目其实是能冲击一等奖的。\n\nTPC 这个项目做了非常多的工作，虽然能预感到后续落地的难度，我还是很期待的，毕竟这也在我们的 roadmap 上。我们用了 io uring，不过貌似也遇到了不少的坑，后面也可以选择 AIO，或者单独的异步线程机制都可以。因为用了新的 raft engine（这个会在 TiDB 5.4 GA），也能很方便地做 parallel log write，充分利用多队列 IO 特性，这个在云上也是很关键的，因为 EBS 单线程的写入 IOPS 其实真不高。另外，后面大家还会去掉 KV RocksDB 的 WAL，这样几个线程池就真能合并，只做计算操作，IO 操作都完全变成异步。\n\n### 通过 Lightning 来加速 add index\n\n这个也是我非常喜欢的一个项目，也是我们在实际 PoC 中多次遇到的一个问题。通过 Lighting 直接 ingest SST，能极大地提升 add index 的速度，决赛实际展示的效果也是把性能提升了一个数量级。这个功能也是在我们的 roadmap 上面的，所以后面我还蛮期待的。另外，其实只要解决了 Lighting ingest SST 过程中，另外操作 update 等操作冲突问题，那么我们完全可以让 Lighting 支持 online 导入。另外在云上面，未来我们可以通过 EMR 这些来进行排序，然后将数据先写入到 S3，再让 TiKV 从 S3 拉取，或者直接使用 S3 的数据。\n\n### MVCC 时光机\n\n这个项目对于运维同学来说是在某些时候能救命的功能。TiDB 在数据存储上面，使用的是 MVCC 机制，也就是一条数据，可能会有多个版本，所以即使用户误删除了这一条数据，我们仍然可以在老的版本上面将其恢复。现在的恢复流程就是先用一个老的版本号（这里就是 timestamp）查询到老的数据，然后将其重新插入回去。这个操作对于单条要恢复的数据还是比较简单的，但如果我们是一批数据的恢复，操作就非常麻烦。这个项目通过 SQL 很好地解决了运维的操作问题。更赞的是，该项目引入了多 safepoint 机制，也就是可以给 TiDB 集群定期做一些全局 snapshot，进行快速轻量级的逻辑备份。不过随着要保存的 snapshot 增多，数据的 MVCC 版本也会增多，对于 scan 这种操作可能会有影响，后面如果我们将历史版本移动到另外的地方，这个问题就能缓解了。\n\n### 让 TiDB 在云上智能的说话 \n\n这个项目我也觉得非常赞，甚至我认为不光是在云上面，TiDB 的智能运维收益，在 OP 上面， TiUP 也是可以借鉴的。我们在升级的时候，可以引入更多的策略，譬如只让副本的 leader 切换一次，或者根据 TiKV 当前的热点、流量等来判断是否该节点能升级。这些策略能很好地降低升级过程对用户业务的影响。\n\n### TiDB 冷热数据分层存储\n\n这个项目获得了本次 Hackathon 的一等奖，再跟本次 Hackathon 另外一个类似项目联合，会为后面 TiDB 跟 S3 的整合打下不错的基础，至少这次 Hackathon 验证了可行性。其实原理很简单，将冷的数据放到 S3，然后将算子尽量地下推到 S3，通过 S3 原生的 Select 功能来加速查询。当然，如果数据已经在 S3，我们还可以通过云上面其他的服务，譬如 Athena， 来做更多的查询聚合操作，加速查询。这次大家都是在通过 partition 做文章，毕竟根据时间片来分 partition 是很常用的一种操作，我们内部现在也在通过 LSM 做一些跟 S3 整合的研究，我还是很期待这些都能在今年看到成果。譬如我们的 TiDB Cloud Developer Tier 集群就可以完全用这套机制来先验证。\n\n## 诊断效能\n\n今年 Hackathon 我个人觉得最开心的应该是凯哥，他现在负责 TiDB 可观测性以及诊断易用性提升，今年的几个项目做好了都可以很好地落地，其实有一些都已经在我们的 roadmap 里面了。\n\n### 自动调配置（Matrix）\n\nMatrix 是 PingCAP 同学跟华中科技大学的同学一起弄的一个项目，不得不说，现在的学生真的是很牛。通过这个项目我才知道，原来 TiDB 5.3 已经有 800 多个参数了，所以后面我们真的需要出一些开发原则，譬如如何来增加参数、配置、session variable 等，不然后续调优会更加困难。其实之前 Hackathon 也有不少的自动 tune 的尝试，但这次我觉得很大的一个突破点，是在于该团队可视化了重要参数的影响程度。\n\n### 自动诊断（Collie）\n\n自动诊断(Collie) 团队的队名（我们这么菜评委不会生气吧）还是蛮有意思的，其实你们一点都不菜，而且还帮助优化了 TiUP diag 的功能，这个已经很厉害了。通过这个项目我才知道，原来我们 metrics 指标已经快 8000 个了，说实话，我觉得再发展下去，人已经没法 debug 了……\n\n### log 分析（Naglfar）\n\n日志也是 TiDB 里面一个急需优化的点，我们打了一些无用的日志，这个后面需要清理，但在诊断问题的时候，我们需要对日志进行关联分析，以及观察某一个日志的趋势，提前发现问题。Naglfar 在这块开了一个不错的头。\n\n### 慢 SQL 诊断（TiVP）\n\n当我终于看到可视化的执行计划时，我几乎留下了激动的泪水。毕竟我们之前诊断慢 SQL 实在是太苦了，那么一大屏的执行计划，几乎叫做没法看，而且如果要对比两个执行计划的异同，就更崩溃了。有了可视化，至少分析到底哪里慢的效率会提升很多，而且后面我们完全可以将 SQL advisor 的功能直接整合到 TiVP 上面，让大家直接在线能进行 SQL bind，add/drop index 这些操作。看完这个项目，我立刻问了下 wish 同学，他直接甩给我一张更漂亮的 Visual Plan 的图，原来已经排在了 roadmap 里面，大家拭目以待。\n\n## 生态扩展\n\n今年的生态，可以用百花齐放来形容吧，看到了太多不一样的东西。我其实一直非常喜欢生态相关的项目，如果说 Hackathon 内核相关的项目是增加 TiDB 的技术深度，那我觉得生态这块就是扩大 TiDB 的广度。对一个数据库来说，『广』就意味着市场占有率的提升。\n\n### TiMatch - 语法完备的分布式图数据库\n\n去年 TiGraph 已经让大家惊艳，今年 TiMatch 更让人期待了。这次易用性更好，而且对于老集群也能直接升级使用。因为 TiMatch 只是内部建立了一套 graph index，通过 TiDB 分布式事务机制，跟原先关系表的数据统一更新。语法上面，借鉴了 Oracle graph 的语法，所以已经是关系完备的了，不过我觉得后面的挑战在于性能上面，希望下一届该项目能给大家展示相关的数据。\n\n### TiLaker: 为 TiDB 插上入湖的翅膀\n\n去年 Hackathon 其实有不少跟 Flink 整合的项目，不过今年决赛就看到一个，说实话我还是有点小失望的。但今年 TiLaker 做的还是挺完备的，毕竟有 Flink Committer 的参与，大家给 Flink 实现了一个 CDC Connector，这样能让 Flink 直接读取 TiDB 的增量数据，同步到下游了。借助 Flink 的能力，让 TiDB 更好地跟下游生态进行了打通，后面也希望有不少的应用案例能出来。\n\n### pCloud\n\n这是一个非常有意思的项目。贵司的 CTO 东旭同学直接上场带货，先抛开他个人极大的现场感染力，从实际来看，pCloud 做得真的很不错。东旭只是展示了产品效果，聊了聊商业模式这些，但我其实是知道这个项目的底层实现的，还是很有挑战的。不过这也给了下一届 Hackathon 参赛的同学另一种参考，一个项目，有时大家更容易关注技术本身，但如果我们是做一个产品，或者一个 SaaS 服务，对于用户及商业的理解也是非常关键的。所以即使大家觉得自己对 TiDB 没太多理解，写不了太硬核的程序，也可以从另外的方向来突破。\n\n### Dujiang Weir\n\n这个项目也挺有意思，晓光在 Weir 上面实现了一些 plugin，扩展了 TiDB 的功能。譬如他写了一个 Redis 的 plugin，为 TiDB 提供了缓存支持的能力，不过我现在在想，是不是 TiDB 自己把 plugin 机制做好一点更好？现在我们的 plugin 是用 Go 自带的 plugin 机制，在可扩展性、可维护性上做得不怎么好，如果我们用了 Hashicorp 的 go-plugin，通过 RPC 来交互，虽然性能有损失，但会不会效果更好？这块未来可以跟晓光他们继续探讨下。\n\n### TiClick\n\n这是我最喜欢的一个项目，我个人给了最高的分数，并不是因为 Sai 同学激情的演讲，也不是因为炫酷的 web 界面，而是我看到了 TiDB 如何能能更好地吸引开发者的一个方向。针对开发者学习 TiDB 这个问题，后面我相信大概率就是一个 SaaS 服务，开发者通过浏览器就能直接学习了解 TiDB。这个项目让我看到了落地的可行性，我也希望能快速的落地。不过我也知道，当下最重要的是让 TiDB Cloud 支持 GitHub SSO 登录、支持 OpenAPI，变得对开发者更加友好，这样才能为后面的生态扩展打下基础。\n\n## 总结\n\n当然，这里只是列出来大部分的项目，还有一些项目没在这里详细点评，譬如 **TiTravel，oom.ai，TiMultiple，Bubbles** 等，都是很不错的项目，后面有空再补充下，大家可以自己去了解关注下。\n\n总的来说，这次 Hackathon 做了两天的评委，在体力和脑力上被严重的 burn out，但还是让我非常兴奋，因为我看到了 TiDB 未来无限的可能性，这次 Hackathon 的 slogan 是 Explore the Sky。Sky 离我们并不遥远，譬如我现在就在高空、在飞机上写这篇文章 :-)\n不过这次 Hackathon 还是有点小遗憾的，我个人认为 Hackathon 的一个精髓就是 24 小时的高强度编程，但因为疫情原因，没法实现，希望疫情在今年能有所好转，大家带着睡袋，在 PingCAP 办公室写程序那种经历还是非常有意思的。  \n\n> 延展阅读：点击查看更多 [TiDB Hackathon 2021 优秀项目分享](https://pingcap.com/zh/blog/?tag=TiDB%20Hackathon%202021)","date":"2022-01-13","author":"唐刘","fillInMethod":"writeDirectly","customUrl":"irresponsible-comments-on-tidb-hackathon-2021-finals","file":null,"relatedBlogs":[]},{"id":"Blogs_64","title":"TiFS 能存数据，为什么不能存文件？","tags":["TiKV"],"category":{"name":"社区动态"},"summary":"本篇文章的作者为龙姐姐说的都对的李晨曦，他们团队在本次Hackathon 比赛中构建了一个基于 TiKV 的分布式 POSIX 文件系统 TiFS，继承了 TiKV 强大的分区容错和严格一致性特性，为 TiKV 生态开辟了一个新的领域。","body":"本篇文章的作者为龙姐姐说的都对的李晨曦，他们团队在本次 Hackathon 比赛中构建了一个基于 TiKV 的分布式 POSIX 文件系统 TiFS，继承了 TiKV 强大的分区容错和严格一致性特性，为 TiKV 生态开辟了一个新的领域。\n\n## 起源\n\n一次给朋友安利 TiDB 时，得知他只有一台机器，那跑 TiDB 集群有什么优势呢？我告诉他可以每块盘跑一个 TiKV 实例，这样实现了多磁盘容灾，就不需要组 RAID 了。\n\n当然最后一句只是玩笑话，毕竟 TiDB 是个数据库，只能做到数据容灾。但转念一想，**如果把文件系统的数据也存进 TiKV，不就能做到文件系统容灾了吗？** 于是我们花了几天写出了 TiFS 的雏形 —— 一个充满 bug 经常死锁的 POSIX 文件系统，但令人兴奋的是这个想法确实可行。\n\n雏形出来后，我们需要考虑更多的问题。比如文件系统基于 TiKV 的优势是什么？又比如 CAP 应该如何取舍？相比于常见的分布式文件系统存储后端，我认为 TiKV 最大的优势是天然支持分布式事务，基于此我们可以保证文件系统的**严格一致性**。如果我们要保证严格一致性，即我们要构建一个 CP 系统，那适用场景应当是通用 POSIX 文件系统，完全覆盖本地文件系统的需求，另外还能实现跨机器的文件协作或满足其它分布式应用的文件存储需求。\n更酷的是，支持多实例协作的单机应用运行在 TiFS 上就可能变成分布式应用，比如 SQLite on TiFS 就是另一个**分布式关系型数据库**！\n\n![1](https://img1.www.pingcap.com/prod/1_63e70736b6.gif)\n\n## 设计细节\n\n### 值\n\nTiFS 一共需要在 TiKV 中存储系统元数据（Meta）、文件元数据（Inode）、文件块（Block）、文件句柄（FileHandler）、符号链接（SymbolicLink）、目录（Directory）和文件索引（FileIndex）共七种值。其中文件块是用户写入的透明数据，符号链接只存储目标路径，而另外五种都是序列化的结构数据。\n\n#### 系统元数据\n\n系统元数据仅有一个用来生成文件序列号（inode number）的整数，其结构如下：\n\n```Rust\nstruct Meta {\n    inode_next: u64,\n}\n```\n\n整个文件系统只有一份系统元数据，且仅在 `mknod` 和 `mkdir` 的过程中被更新。\n\n#### 文件元数据\n\n每个文件都有一份对应的文件元数据，其结构如下：\n\n```rust\nstruct Inode {\n    file_attr: FileAttr,\n    lock_state: LockState,\n    inline_data: Option<Vec<u8>>,\n    next_fh: u64,\n    opened_fh: u64,\n}\n```\n\n其中 `file_attr` 字段中存储了 POSIX 文件系统所必要的元数据，比如文件序列号、文件大小、块数量等，详细结构可[参考文档](https://docs.rs/fuser/0.7.0/fuser/struct.FileAttr.html)；`lock_state` 字段存储了当前的上锁状态和持锁人，用于实现 `flock；inline_data` 字段可能会存储少量文件内容，用于提升小文件的读写性能；`next_fn` 字段是一个自增整数，用于生成文件句柄；`opened_fn` 字段用于记录打开状态的文件句柄数量。\n\n#### 文件句柄\n\n文件系统对用户的每次 open 调用生成一个文件句柄，仅用于存储句柄的读写限制，其结构如下：\n\n```rust\nstruct FileHandler {\n    flags: i32,\n}\n```\n\n#### 目录\n\n每个目录都需要存储一份子文件列表以实现 `readdir`，列表中的每一项都存储了一个子文件的文件序列号、文件名和文件类型，其结构如下：\n\n```rust\ntype Directory = Vec<DirItem>;\n\nstruct DirItem {\n    ino: u64,\n    name: String,\n    typ: FileType,\n}\n```\n\n#### 文件索引\n\n我们可以直接遍历目录来实现文件查找，但为每个文件链接创建索引显然是更高效的解决方案。每个文件索引仅含有目标文件的序列号，其结构如下：\n\n```rust\nstruct Index {\n    ino: u64,\n}\n```\n\n### 键\n\nTiKV 本身只提供简单的键值对存储，键和值都是不定长的字节数组，所以设计系统之前需要给键分逻辑区域。TiFS 一共有系统元数据、文件元数据、文件块、文件句柄和文件索引五种键，其中文件块类的键可以用来存储文件块数据、符号链接和目录，另外四种键都只用于存储前文提到的同名值。\n\n我们根据第一个字节区分不同类的键，这个字节可称为键的域（scope）。键的字节数组通用布局如下：\n\n![2](https://img1.www.pingcap.com/prod/2_eb46561370.png)\n\n#### 系统元数据\n\n系统元数据域只有唯一键值对，其键的字节数组布局如下：\n\n![3](https://img1.www.pingcap.com/prod/3_39626e3409.png)\n\n#### 文件元数据\n\n文件元数据域的键仅含有大端序编码的文件序列号，这样所有的文件元数据都顺序地存储在 TiKV 上，可以在 [`statfs`](https://man7.org/linux/man-pages/man2/statfs.2.html) 操作时直接用 TiKV 的 `scan` 接口扫描出所有文件的元数据。\n\n文件元数据键的字节数组布局如下：\n\n![4](https://img1.www.pingcap.com/prod/4_5ccb7c401a.png)\n\n#### 文件块\n\n文件块域的键由文件序列号和块序列号的大端序编码构成，这样同一文件的所有的文件块都顺序地存储在 TiKV 上，可以在读取大段数据时直接使用 TiKV 的 `scan` 接口一次扫描出所需的文件块。\n\n文件块键的字节数组布局如下：\n\n![5](https://img1.www.pingcap.com/prod/5_5a3502350f.png)\n\n#### 文件句柄\n\n文件句柄域的键由文件序列号和句柄号的大端序编码构成，其字节数组布局如下：\n\n![6](https://img1.www.pingcap.com/prod/6_97d7524015.png)\n\n#### 文件索引\n\n文件索引的键由大端序编码的目录文件序列号和 utf-8 编码的文件名构成，其字节数组布局如下：\n\n![7](https://img1.www.pingcap.com/prod/7_c670514518.png)\n\n### 一致性\n\nTiKV 同时支持乐观事务和悲观事务，但由于 Rust 版客户端只提供了实验性的悲观事务支持，以及无冲突情况下悲观事务性能较差，目前TiFS 只使用了**乐观事务**。\n\n## 应用场景\n\nTiFS 可以用于大文件存储，但它相比于现有的大文件存储方案没有特别的性能或存储效率上的优势，它的主要使用场景是**小文件读写和复杂的文件系统操作**。git 远程仓库可以直接使用 TiFS 存储项目并运行 git 任务，比如 rebase 或 cherry-pick，而无需先转存到本地文件系统；多节点应用读写同一文件时可以直接使用 flock 来解决冲突。它的空间管理无需复杂的 SDK 或 API 接入，只需要调用简单的文件系统 API 或 shell 脚本。\n\n另外，像文章开头所说的，支持多实例协作的单机应用运行在 TiFS 上就可能变成分布式应用，如运行在 TiFS 上的 SQLite 就成了分布式关系型数据库。当然这种场景对单机应用本身的要求比较严苛，首先应用本身得支持单机多实例，另外尽量不依赖 page cache 或其它缓存以避免写入不可见。\n\n## 测试与性能\n\n目前我们还没有给 TiFS 写测试，开发过程中我们一直以 [pjdfstest](https://github.com/pjd/pjdfstest) 为正确性基准并最终通过了它。但 pjdfstest 并不能覆盖读写正确性和并发下正确性，后面需要再跟进其它的测试。\n\n从理论上来说 TiFS 的读写性能的影响因素主要有三个：文件系统块大小、网络带宽延迟和负载块大小。下面我们给出了一份 [benchmark](https://github.com/Hexilee/tifs.benchmark) 的[结果](https://docs.google.com/spreadsheets/d/1QusW0FYAjLRzDN9LbMUTLvwuxtZvNz_g_1GIrwXnevc/edit?usp=sharing)，并针对读写 $IOPS$ 和读写速度作出了四张图表。\n\n我们首先来讨论 $IOPS$ 的变化规律，如下两张图分别是顺序写 $IOPS$ 和顺序读 $IOPS$ 随负载块大小的变化，四条折线代表不同的文件系统块大小和数据副本数。\n\n![8](https://img1.www.pingcap.com/prod/8_f90ba2851c.png)\n\n![9](https://img1.www.pingcap.com/prod/9_d93b6dcb26.png)\n\n由于顺序读写的 IO 操作是线性的，每次 IO 操作都是一次 TiKV 事务。如果我们忽略每次 IO 操作之间的细微区别，那一次 IO 操作的耗时 $T$ 就是 $IOPS$ 的倒数，且 $T$ 由 FUSE 的 IO 耗时 $T_f$，TiFS 本身的逻辑耗时 $T_c$ 、 网络传输耗时 $T_n$ 和 TiKV 的逻辑耗时 $T_s$ 叠加而成。如果不考虑流式处理，耗时就是线性叠加，即 $T=T_f+T_c+T_n+T_s$,  $IOPS=1/T_f+T_c+T_n+T_s$。\n\n只考虑读的情况，$T_f$ 与负载块大小正相关； $T_n$ 和 $T_s$ 跟负载块和文件系统块中的较大者正相关（因为 TiFS 每次 IO 操作必须读写文件块整数倍的数据），而更大的流量可能会造成更多的网络和磁盘 IO 耗时；$T_c$ 的理论变化规律未知。\n\n> TiKV 是个非常复杂的系统，其内部也可分为逻辑耗时、磁盘 IO 耗时和网络耗时。本文在性能分析时暂且将 TiKV 简化，只考虑单副本的情况。\n\n图读 $IOPS$ 随负载大小变化 中，文件块和负载块均为 $4K$ 时，随着负载的增大 $T_f$, $T_n$ 和 $T_s$ 都在增加，故 $IOPS$ 减小。文件块 $64K$ 和 $1M$ 的情况下，当负载块小于文件块，$T_n$ 和 $T_s$ 几乎不变，$T_f$ 增大，$IOPS$ 减小；当负载块大于文件块，$T_f$, $T_n$ 和 $T_s$ 都在增加，故 $IOPS$ 持续减少。变化折线大致符合预期。\n\n> 图中横坐标为对数距离，且取样点过少，斜率仅供参考。\n\n顺序写数据时，如果负载块小于文件块，则 TiFS 需要先读一个脏文件块，会造成额外的 $T_c$ 和 $T_n$。这一点在文件块比较大时比较明显。如图写 $IOPS$ 随负载大小变化 中，文件块 $1M$ 时 $IOPS$ 的极大值明显处于文件块与负载块相等时。\n\n另外我们可以发现，负载块和文件块为 $4K$ 或 $64K$ 时的 $IOPS$ 的几乎相等的。此时每秒最小流量 $4K \\times 110=440K$，每秒最大流量 $64K \\times 100=6.25M$，对网络或者磁盘的压力很小。在流量足够小的情况下可以认为 $IOPS$ 到达到了上限，此时 $T_n$ 的主要影响因素变成了网络延迟（本机测试可以认为是 $0ms$）。特别在写 $IOPS$ 随负载大小变化 图中，文件块和负载块在 $4K$ 和 $64K$ 之间变化对 $IOPS$ 几乎无影响。我们称此时的 $T$ 为 TiFS 在当前网络环境下的**固有操作延迟**，它主要由 $T_c$ 和 $T_s$ 决定。TiFS 和 TiKV 的逻辑耗时造成了固有延迟，过高的固有延迟会造成小文件读写体验很糟糕，但具体的优化思路还需要进一步的 perf。\n\n读写速度等于 $IOPS$ 与负载块的乘积，而 $IOPS$ 在负载块 $4K$ 到 $1M$ 之间没有剧烈变化，我们很容易就能看出负载块 $1M$ 时读写速度达到最大值。下面两张是负载块 $1M$ 时不同集群配置下的读写速度对比图。\n\n> 文件块 $64K$ 下未开启 [Titan](https://github.com/tikv/titan) 的对比图已有单副本数据，三副本数据仅供参考，未进行重复对比。\n\n![10](https://img1.www.pingcap.com/prod/10_e76157f43a.png)\n\n![11](https://img1.www.pingcap.com/prod/11_a327976644.png)\n\n我们可以看到写速度受**文件块大小和 Titan 的影响比较大**，读速度则几乎不受影响。文件块越小，TiKV 需要写入的键值对越多，导致了额外耗时；但文件块过大会导致 RocksDB 写入性能不佳，开启 Titan 可以减少不必要的值拷贝，明显提升性能。\n\n## 未来\n\nTiFS 在架构上存在的一个问题是文件块存储成本比较高。TiKV 采用多副本冗余，空间冗余率（实际占用空间/写入数据量）一般 3 起步；而像 HDFS 或 CephFS，JuiceFS 等支持 EC 冗余模式的分布式文件系统冗余率可降到 1.2 到 1.5 之间。EC 冗余在写入和重建数据时需要编解码，均需要额外的计算资源。其在写入时可以降低网络开销和存储成本，但重建时一次需要读取多个数据块，有额外的网络开销，**是一种牺牲部分读性能以降低写入时网络开销及存储成本的冗余策略**。\n\n目前 TiKV 要支持 EC 冗余还比较困难，后面 TiFS 会尝试支持 EC 冗余的对象存储来存文件块以降低存储成本，但近期的工作还是集中在**正确性验证和性能调优**。正确性验证部分包括找其它的开源文件系统测试和自建测试。性能调优部分包括 TiFS 的本身的调优工作和 TiKV 的高性能使用，以降低固有延迟。如果你对[这个项目](https://github.com/Hexilee/tifs)感兴趣，欢迎来试用或讨论。","date":"2021-04-01","author":"李晨曦","fillInMethod":"writeDirectly","customUrl":"tifs-can-save-data-but-not-files","file":null,"relatedBlogs":[]},{"id":"Blogs_158","title":"Chaos Mesh 的 Chaos Engineering as a Service 探索之路","tags":["Chaos Mesh"],"category":{"name":"社区动态"},"summary":"本篇文章的作者为 CAAS 团队的王相与于畅，他们在本次 Hackathon 比赛中基于 Chaos Engineering as a Service 的理念，对 Chaos Mesh 进行改造，以下就来看看他们的探索历程。","body":"Chaos Mesh 已经开源一周年了，目前是 CNCF 的 sandbox 项目，在国内外发展良好，有了很多的 Contributor 和关注度。\n\n但是目前 Chaos Mesh 仍然存在一些需要继续建设的方面：\n\n*   需要继续提高易用性。目前有些 Chaos 的功能较为复杂，用户在创建 Chaos 实验后，可能还需要人工确认实验是否生效，需要改进 Metrics 以及与监控系统的联动。\n\n*   主要支持 K8s 环境。目前 Chaos Mesh 主要针对 K8s 环境设计的，而且每个 K8s 集群都需要部署一个 Chaos Mesh，无法统一进行管理。另外，支持物理机的混沌实验工具 Chaosd 支持的功能有限，而且通过命令行注入实验的方式对用户不太友好。\n\n*   暂不支持插件。目前添加自定义 Chaos 只能通过修改源码，暂不支持插件以及 Go 以外的语言，不利于新 Chaos 功能的扩展。\n\n*   没有原生支持编排。目前可以[通过 Argo 来做编排](https://pingcap.com/blog-cn/building-a-distributed-test-platform-based-on-chaos-mesh-and-argo/)，但是还不够易用。Chaos Mesh 计划是在 V2.0 版本支持原生编排，这样也可以闭环做一些回调操作。\n\n总体来说，Chaos Mesh 距离 Chaos Engineering as a Service 还需要继续建设，并且还有很大的想象空间。\n\n## 混沌工程即服务（Chaos Engineering-As-a-Service）\n\n文章 [The benefits of chaos engineering-as-a-service](https://jaxenter.com/chaos-engineering-service-144113.html) 是这么定义的：\n\nCAAS（ChaosEngineering-As-a-Service）意味着可以快速的看到直观的图形化界面，开箱即用的集成一切需要进行实验的东西。\n\n业界也有基于 CAAS 提供服务的厂商，比如 [Gremlin](https://www.gremlin.com/)。\n\n我的解读，Chaos Engineering as a Service 需要有一个统一的管理入口，可以便捷地通过界面操作，填写配置，创建 Chaos 实验；可以看到实验的状态和一些监控指标数据，对比任务周期的效果；可以做一些暂停、归档等操作管理实验；可以拖拽式编排 Chaos 实验。\n\n目前已经有一些公司基于自己真实的需求对 Chaos Mesh 进行了“魔改”，让它更像 Chaos Engineering as a Service，比如[网易伏羲](https://chaos-mesh.org/blog/how-a-top-game-company-uses-chaos-engineering-to-improve-testing)、[FreeWheel](https://mp.weixin.qq.com/s/0monDPkAlMk7Yhq9swW7gQ)。另外我们也在 TiDB Hackathon 2020 的比赛中做了一个相关的课题，大致有了 Chaos Engineering as a Service 的雏形。\n\n## TiDB Hackathon 2020 的实践\n\n### 架构改造\n\n基于 Chaos Engineering as a Service 的理念，我们对 Chaos Mesh 进行改造。Chaos Mesh 目前的架构比较适合单 K8s 集群使用，而且是只针对 K8s 环境设计的。架构图如下：\n\n![1-架构图](https://img1.www.pingcap.com/prod/1_805f6b1ce8.png)\n\n我们对 Chaos Mesh 的架构进行了简单的调整，将 Dashboard 独立出来，不再与某个特定的 K8s 环境绑定。如果 Dashboard 部署在 K8s 集群外，则通过界面添加 K8s 集群；如果 Dashboard 部署在集群内，则可以通过环境变量自动获取集群信息。 \n\n![2-dashboard](https://img1.www.pingcap.com/prod/2_dashboard_9e773d141c.png)\n\n可以通过 Dashboard 注册 Chaos Mesh（实际注册的是 K8s 配置），Chaos Mesh 的 Controller Manager 组件也可以通过配置主动向 Dashboard 主动注册。Dashboard 与 Controller Manager 的交互通过 CRD 来完成。Controller Manager 监听到有 chaos-mesh 的 CRD 事件后，会调用 Chaos Daemon 做相应的 chaos 实验操作，因此只要 Dashboard 可以操作 CRD，即可完成对 Chaos 实验的管理。\n\n运行在物理机上的 Chaosd，原本是命令行的形式，而且功能比较单一。\n\n![3-命令行](https://img1.www.pingcap.com/prod/3_f4acaa0f23.png)\n\n我们改造了 Chaosd，支持 RESTful API。将 Chaosd 的服务模式进行了增强，可以通过解析 CRD 格式的 JSON/YAML 来配置 Chaos 实验。\n\nChaosd 可以通过配置主动向 Dashboard 注册，增加 heartbeat 机制，在注册到 Dashboard 后，定期向 Dashboard 发送心跳，方便 Dashboard 维护 Chaosd 节点状态。同时，也可以使用 Dashboard 界面添加 Chaosd 节点。\n\n我们也给 Chaosd 增加了定时调度与实验生命周期管理，实现 K8s 环境所具备的功能，统一 K8s 环境与物理机环境。\n\n![4-dashboard](https://img1.www.pingcap.com/prod/4_dashboard_c8cdc905c5.png)\n\n改造之后的 Chaos Mesh 架构如下：\n\n![5-改造后架构图](https://img1.www.pingcap.com/prod/5_69527c78dc.png)\n\n要解决的另外一个问题是如何判断 Chaos 实验是否生效。以负载实验为例，在注入了 StressChaos 之后，需要进入到实验选取的 Pod 中，查看是否有 stress-ng 的进程，再使用 top 等系统命令查看 CPU 和内存消耗，这样才能确定 Chaos 实验注入成功了。\n\n改造后，在 Chaos Daemon、Chaosd 中集成了 node_exporter，实现节点 Metrics 采集；K8s 集群内部署 kube-state-metrics ，结合 cadvisor，实现 K8s Metrics 采集。配合 Prometheus + Grafana 即可实现对 Metrics 监控，基于 Metrics 监控可以便捷的查看实验结果状态。\n\n![6-监控](https://img1.www.pingcap.com/prod/6_fd40b8aef0.png)\n\n### 一些不足之处\n\nMetrics 主要是解决三个问题：\n\n1.  如何观测 Chaos 被成功注入\n\n2.  如何观测 Chaos 注入以后对于服务的影响，并能做周期性的对比\n\n3.  异常 Chaos 事件的相应\n\n综上，可能需要从三个方面入手，实验数据 Metrics、正常指标监控、实验 Event。也就是说，目前还欠缺：\n\n*   实验数据 Metrics，例如注入网络延迟的具体延迟时间、模拟负载的具体模拟值等等。\n\n*   实验 Event，实验创建、删除、运行周期的 K8s Event。\n\n可以参考 [https://github.com/litmuschaos/chaos-exporter#example-metrics](https://github.com/litmuschaos/chaos-exporter#example-metrics)。\n\n## 一些“可用的”工具及设想\n\n### 编排\n\n完整的实验闭环，既需要有对 Chaos 的探索，又需要对实验结果做相应的处理，并反馈给混沌工程系统\n\n![7-实验闭环](https://img1.www.pingcap.com/prod/7_70db3fa174.png)\n\n目前开源的 Chaos 工具，大多都只做了有限的探索，缺少后续的反馈。基于可观测性组件，可以实时感知 Chaos 实验的结果，基于实验结果数据做对比与分析。\n\n反馈与闭环，另一个重要组件的就是实验的编排与管理。目前社区已经有了相关的 [WorkFlow 提案](https://github.com/chaos-mesh/rfcs/pull/10)，以及基于提案的相应[实现](https://github.com/chaos-mesh/chaos-mesh/pull/1418)。基于 WorkFlow，可以很轻松的实现对 Chaos 实验的编排、回调，也可以很方便的和其他系统进行联动。例如，可以在 CI/CD 阶段跑 Chaos；可以在执行灰度/金丝雀发布后跑 Chaos。\n\n同时，最重要的是可以让 Chaos 实验实现闭环。比如对某个 Pod 进行网络延迟测试，延迟是 100ms。通过可观测性组件可以轻松观测到网络延迟的变化，同时基于编排可以使用 PromQL 或者其他 DSL 查询到这个 Pod 的服务是否可用。假设服务不可用，就会得到一个结论，当延迟大于等于 100ms 的时候，服务不可用。但这远远不够，因为 100ms 不是阈值，更需要一个相对准确的阈值来保证服务的 SLO，而恰好可以通过编排修改 Chaos 实验的实验值来反复实验。同时，也需要知道服务在不同网络延迟下的表现，以及是否能达到预期。\n\n#### 通过编排再来看混沌工程\n\n混沌工程和和故障测试类似。故障测试通过对预先设想到的可以破坏系统的点进行测试，但是并没能去探究上述这类更广阔领域里的、不可预知的、但很可能发生的事情。在测试中，要进行断言：即给定一个特定的条件，系统会输出一个特定的结果。\n\n故障测试一般来说只会产生二元的结果，验证一个结果是真还是假，从而判定测试是否通过。严格意义上来说，这个实践过程并不能发掘出系统未知的或尚不明确的认知，它仅仅是对已知的系统属性可能的取值进行测验。\n\n实验可以产生新的认知，而且通常还能开辟出一个更广袤的对复杂系统的认知空间。故障注入则是对一个特定的条件、变量的验证方法。混沌工程是发现新信息的实践过程。\n\n### 数据格式\n\nCRD 其实很好的提供了一种对数据格式定义的方式。基于 chaos-mesh 的 CRD，转换成 JSON，即可实现在组件间通信。\n\n站在数据格式的角度看 Chaosd，其实 Chaosd 只是对 CRD 数据(JSON 格式)的消费与注册。那么，是否有这样一种可能，只要实现对 CRD 数据的消费以及自身状态的注册，即可实现或覆盖不同场景的 Chaos 实验。\n\n### 插件\n\nChaos Mesh 目前对插件支持比较有限，只能通过扩展 CRD 的形式，具体可见[官方文档](https://chaos-mesh.org/docs/development_guides/develop_a_new_chaos)。\n\n但这样就会有两个问题：\n\n1.  开发者必须使用 Golang 来做扩展开发，对开发者还是有一定要求的，虽然 Golang 是高级 PHP(PHP 是世界上最好的语言)。\n\n2.  扩展的代码需要合进项目，合进主代码又有可能引发额外的风险，毕竟没有 BPF 那种安全机制(是不是文章中包含 BPF 就能蹭一波热度)。\n\n可能需要探索一种魔(ye)幻(lu)的(zi)插件方式。基于 Go 的插件，HashiCorp 出过一个 [go-plugin](https://github.com/hashicorp/go-plugin)，但还是基于 Go。回归本质， Chaos Mesh 其实是基于 CRD 进行 Chaos 实验。也就是说，只要能够生成、监听处理、删除 CRD 就可以完成混沌实验。基于 client-go？开发 Controller、Operator 操作 CRD？不，还有其他好(ye)办(lu)法(zi)。\n\n![8-crd](https://img1.www.pingcap.com/prod/8_crd_0f6e05fef2.png)\n\n可以统一处理 CRD 事件，然后通过 HTTP 回调的形式实现对 CRD 的操作，可以不使用 Golang，有 HTTP API 即可。思路略向上文数据格式中提及的部分。开源实现的相关参考 [Whitebox Controller](https://github.com/summerwind/whitebox-controller)。\n\n只是 HTTP Hook 可能还够，还有更好的野路子，比如 Wasm。需要调用 Chaos 实验逻辑的时候调用 Wasm 程序就好啦。业界也基于 Wasm 做插件的例子可以参考，比如 Vector 的 [WASM Transform](https://vector.dev/docs/reference/transforms/wasm/)。BTW，TiDB Hackathon 2020 上的 [TiDB UDF](https://pingcap.com/blog-cn/effective-tidb-udf-through-wasm/) 就是用 Wasm 实现的。\n\n通过命令行、API、面板查看 Chaos 实验的状态太繁琐？试试 SQL？再次回归本质， Chaos Mesh 是基于 CRD 的，那么只要能读取、操作 CRD 即可。使用 SQL 操作 K8s 的开源方案还是有一些的，比如 [Presto 的 connector](https://github.com/xuxinkun/kubesql)，[osquery 的扩展](https://github.com/aquasecurity/kube-query)等等。\n\n业界也有一些基于 SDK 的扩展方式，比如 [Chaos Toolkit](https://docs.chaostoolkit.org/reference/api/experiment/)。\n\n### 融合其他混沌工具\n\n与现有的 Chaos 工具结合会让整体的生态更强大，毕竟用户的 Chaos 场景可能很难穷尽。\n\n例如，Litmus 的 [K8s 实现](https://github.com/litmuschaos/litmus-go/tree/master/chaoslib/powerfulseal)是基于 [PowerfulSeal](https://github.com/powerfulseal/powerfulseal) 的，Litmus 的[容器实现](https://github.com/litmuschaos/litmus-go/tree/master/chaoslib/pumba)是基于 [Pumba](https://github.com/alexei-led/pumba) 的。\n\n当然还有针对 Kubernetes 的 [Kraken](https://github.com/cloud-bulldozer/kraken)、针对 AWS 的 [AWSSSMChaosRunner](https://github.com/amzn/awsssmchaosrunner)、针对 TCP 的 [Toxiproxy](https://github.com/shopify/toxiproxy) 等等。也有比较新潮的，例如基于 [Envoy](https://docs.google.com/presentation/d/1gMlmXqH6ufnb8eNO10WqVjqrPRGAO5-1S1zjcGo1Zr4/edit#slide=id.g58453c664c_2_75) 的、基于 Istio 的。生态还是比较丰富的，暂不一一例举。可能需要一种通用的模式，来管理如此之前的场景。业界也有一些开源的参考，比如 [Chaos Hub](https://hub.litmuschaos.io/)。\n\n## 一些“实践经验”\n\n其实是在 360 的野路子瞎搞。整体架构还是围绕 K8s 的，大部分功能基于 Chaos Mesh 魔改。\n\n物理节点层面：\n\n*   支持执行物理机执行自定义脚本。CRD 配置脚本路径，通过 Chaos Daemon 运行自定义 Shell 脚本，但需要特权模式运行容器，不是很友好。\n\n*   基于自定义 Shell 脚本模拟 reboot、shutdown、Kernel Panic。\n\n*   基于自定义 Shell 脚本将节点网卡 down 掉(随机 down 掉节点，可能会造成物理机启动失败)。Shell 脚本内实现 ifdown、ifup 即可。\n\n*   使用 sysbench 制造上下文频繁切换。模拟“吵闹的邻居”。\n\n*   基于 BPF 的 seccomp 实现对容器的系统调用拦截。传递 PID，基于 PID 过滤即可。\n\n容器层面：\n\n*   随机修改 Deployment 的副本数量，测试应用的流量是否有异常。\n\n*   基于 CRD 对象嵌套，在 Chaos CRD 中填写 Ingress 对象，模拟接口限速。\n\n*   基于 CRD 对象嵌套，在 Chaos CRD 中填写 Cilium Network Policy 对象，模拟网络时好时坏。\n\n业务层面：\n\n*   支持自定义 Job。目前 Chaos Mesh 主要是基于 Chaos Daemon 实现注入，不具备调度的公平性以及亲和性，通过 Controller Manager 针对不同的 CRD 类型，直接创建 Job 即可实现。\n\n*   自定义 Job 跑 [Newman](https://github.com/postmanlabs/newman)，随机修改 HTTP 参数。实现 HTTP 接口层面的 Chaos 实验，模拟用户异常行为。\n\n综上，是一些对 Chaos 的个人拙见、对 Chaos Mesh 的胡思乱想、基于 Chaos Mesh 的野路子混沌工程系统落地实践。全文仅供参考，不建议在生产环境模拟使用，如造成混沌状态，纯属巧合。\n\n> “忘记你已经学到的。” — Yoda\n\n## 一些可以阅读的资料\n\n*   [https://principlesofchaos.org/zh/](https://principlesofchaos.org/zh/)\n\n*   [https://netflixtechblog.com/the-netflix-simian-army-16e57fbab116](https://netflixtechblog.com/the-netflix-simian-army-16e57fbab116)\n\n*   [https://medium.com/better-practices/chaos-d3ef238ec328](https://medium.com/better-practices/chaos-d3ef238ec328)\n\n*   [Learning Chaos Engineering: Discovering and Overcoming System Weaknesses through Experimentation](https://www.oreilly.com/library/view/learning-chaos-engineering/9781492050995/)\n\n*   [Chaos Engineering: System Resiliency in Practice](https://www.oreilly.com/library/view/chaos-engineering/9781492043850/)\n\n*   [Chaos Engineering Observability](https://www.oreilly.com/library/view/chaos-engineering-observability/9781492051046/)","date":"2021-03-04","author":"于畅,王相","fillInMethod":"writeDirectly","customUrl":"chaos-engineering-as-a-service","file":null,"relatedBlogs":[]},{"id":"Blogs_55","title":"大力出奇迹，GPU 加速 TiDB ｜ TiDB Hackathon 2020 优秀项目分享","tags":["TiDB Hackathon 2020"],"category":{"name":"社区动态"},"summary":"本篇文章将通过 Mods 团队与云启资本合伙人陈昱的对话，揭秘团队赛前幕后的精彩故事。","body":"![Banner](https://img1.www.pingcap.com/prod/Banner_adbc799b75.jpg)\n\nMods 团队的两位成员孙若曦、徐飞相识已久，笑称对方为「 最默契的人 」。在本次Hackathon 中他们使用 GPU 加速技术，为 TiDB 带来新的扩展性提升。该项目最终获得三等奖和云启资本 — 最具市场潜力奖。今天我们将分享作为决赛第一组进行答辩的 Mods 团队与云启资本合伙人陈昱的访谈 ，探秘三位工程师（陈昱此前曾是 Google 的工程师，曾和 Spanner 论文其中一个作者坐在同一格子间里）关于 「 GPU 加速 TiDB 的紧张故事 」。\n\n## Q：Mods 团队的名字的由来和组队趣事儿？\n\n**Mods ：** 我们队伍的两个人都是毕业就进入 N 厂（英伟达），一起在上海的 GPU Mods 组，后来又都进入了 P 社（ PingCAP）。这次我们想做一个 GPU 加速的项目，索性就直接用了 Mods 这个队名。\n\n## Q：很好奇，英伟达大家都会去做偏 AI 的东西，当时为什么会加入一家数据库公司？\n\n**Mods ：** 加入 PingCAP 的原因是我们都认为大数据和数据库市场的前景是比较广的，而且我们在英伟达更多的也是做一些偏底层、偏基础设施方面的工作，我们觉得这方面的经验是有可能被应用到同样是基础软件的大数据和数据库这方面的工作上的，因此就做了这样的选择。\n\n## Q：陈昱老师也是工程师出身，最终选择 Mods 团队的原因有哪些？\n\n**云启资本陈昱：** 早在 2017 年，我就关注 GPU 加速的应用，在我看来用 GPU 来加速数据分析，是蛮有商业价值的。\n\n除了这个项目的 idea 我很喜欢之外，从投资人的角度来看，我更看中项目的独立性。比如本次获得第一名的 UDF 的项目我也很喜欢，但是它需要依附 PingCAP 的生态，比较难独立孵化，当然在生态里实现也很不错，但是从投资人的角度考虑，会更希望有朝一日可以孵化出一个独立的公司。\n\n## Q：陈昱老师之前应该也有参加过 Hackathon 吗，是如何看待这种活动形式的？\n\n**云启资本陈昱：** 之前在谷歌比较少会有公司范围的 Hackathon，更多的可能是在组内或者大组内对一个项目本身的 Hackathon ，性质也偏向于修复臭虫和做一些平时优先级没这么高的任务，很少做大 feature。\n\n以前在 Google 的时候有所谓的 “20 时间”，就是员工可以花 20% 的时间做任何事情，这和 PingCAP 的 Hackathon 在某种意义上是很类似的，给大家一个机会去实现自己的想法，很著名的 Gmail 最初就是从这 “20 时间”中创造出来的。对 PingCAP 来说也是同样的，每年都会有几个项目最后会成为 PingCAP 产品的一部分。\n\n**如果没有 Hackathon 这个机会，可能很多 idea 就会永远被埋没在沙堆里面，因为大家日常工作都会有自己的开发计划，都会忙着往前推进，很少有时间去思考、去实现一些很创新的想法，所以我觉得这个机制是很好的。**\n\n## Q：Mods 团队可以分享一下最初做这个项目的灵感和分工吗？\n\n**Mods：** 我们两人之前在英伟达都是做 GPU 相关的工作，虽然后来更多的是在做大数据方向，但是对 GPU 的大方向还是比较关注的。恰巧去年在网上看到一家硅谷公司，他们的团队做了一个 GPU 的关系型数据库，当时的 benchmark 效果很惊人，我们顺着源代码研究发现已经有一些相对比较成熟和独立的使用 GPU 来加速数据分析的基础组件，印象很深刻。今年 Hackathon 招募出来之后，我们就第一时间想到了这个 idea。\n\n![1](https://img1.www.pingcap.com/prod/1_6f24694854.png)\n\n![2](https://img1.www.pingcap.com/prod/2_962df4cf74.png)\n\n分工方面主要还是从项目的整体设计和架构出发，先头脑风暴出一个比较干净和优雅的分层，架构分层干净意味着可以互相解耦，各自独立开发，从而效率得到保证。接下来再细化分层之间交互的接口，我们对整个分层之间的 API 做了很精细的设计，具体细化到了每个 API 的参数、返回值、调用顺序、并发模型等等。虽然前期的设计和讨论花了比较长的时间，但带来了更多中后期开发效率上的收益（虽然整个项目周期也没有很长，笑～），各自实现自己模块的时候，不会被对方的节奏和进度打乱。\n\n![3](https://img1.www.pingcap.com/prod/3_6da905b174.png)\n\n具体的分工上，我会去实现 GPU 计算层的整体框架和一部分 GPU 算子，徐指导实现 TiDB 侧的对接，包括执行计划的翻译以及执行器的实现，以及另一部分 GPU 算子。我们知道 Apple 在 2020 年已经不再支持 N 卡和 CUDA 开发了，而我们两个的主力开发机都是 MacBook，只有我家里一台装了 RTX 2080 的台机可以用来写 GPU 代码。这时候架构上的分层设计就体现出了它的意义。我们将算子的具体实现从框架层剥离开，并在非 GPU 环境下提供了一套十分原始但是可运行的 CPU 算子实现，使得 GPU 无关的代码可以搭配这套 CPU 算子在非 GPU 环境下独立进行开发和调试，这就极大减小了我们对我那个台机的依赖。至于 GPU 算子，只能在我的台机上开发调试，我和徐指导基本上是分时复用，因为作息配合也比较默契所以没什么冲突（或者发生冲突时我把徐指导 kill 掉因为毕竟机器在我手里）。\n\n另外一点，就像前面提到的，我们通过分层设计以及抽象出一组简洁的 API，使得整个项目具有很大的架构上的灵活性。我们只需在 TiKV 或 TiFlash 中完成与 TiDB 对接相同的工作，就可以将这套算子整合到其中，从而实现下推到 TiKV 和 TiFlash 的计算也通过 GPU 来加速执行，这样就具备了扩圈到整个 TiDB 生态甚至生态之外的扩展性。\n\n![4](https://img1.www.pingcap.com/prod/4_b26cff1db4.png)\n\n## Q：这个东西实际上是可以泛化去支持其他（素板卡）类型，比如说 A 卡我能不能用（OpenCL ）去做加速或者怎么样？\n\n**Mods：** 没错，前面提到我们将算子的具体实现从框架层剥离开，并且为了减小开发环境的制约而实现了一套原始但可运行的 CPU 算子。这个方法同样适用于为 GPU 算子提供不同的实现，比如提问中的 OpenCL（N 卡和 A 卡都能跑），甚至可以考虑在 FPGA 上面做一些支持。而这些只需要通过编译开关简单的控制即可。\n\n## Q：听完 Mods 团队分享的前期灵感及分工故事，陈昱老师有什么其它想法希望分享的？\n\n**云启资本陈昱：** 大家都知道，我们一直在持续做基础软件方向的投资。有几个关于大数据的方向我比较看好：数据库即服务，批流一体数仓，还有就是基于新型硬件做优化的数据库。数据库是个复杂的系统，不单纯是软件，硬件对它的设计也有很大的影响。像 Mods 做的 GPU 加速就是个很好的例子，还有就是非易失存储，用好了能极大的降低 IO 延迟。\n\n## Q：Mods 团队是第一个进行决赛 demo 的团队，这里有什么缓解紧张故事可以分享的？\n\n**Mods：** 这是一个紧张的故事，最开始我是听到隔壁组的抽签结果，他们第二个答辩，我们还安慰他们说没事。结果几秒钟之后看到我们竟然是第一个答辩，然后他们就来安慰我们了。当时的第一反应是来不及紧张了，直接抱着电脑去调试设备。另外在场的其他组的小伙伴还是给了我们很大的鼓励，说早早答辩完，就可以一下午吃吃喝喝看别的组翻车，多舒服。虽然可能这些话他们自己都不大信，但是确实让我们心情平静了很多。我们的心里建设也就是给自己打一针鸡血，干就完了，争取把场子热起来，给大家开个好头。\n\n## Q：陈昱老师是如何在看完剩下 27 个项目之后还没有变心的？\n\n**云启资本陈昱：** 哈哈哈，其实在最开始看 RFC 的时候，就很喜欢他们。而且早一点讲也是有好处的，大家可以有更多的精力来关注他们的演讲，因为一天二十几个项目听下来对评委的体力和心力有很大的消耗。他们有个优势的 demo 效果特别好，这和他们合理分配时间不无关系。这次答辩过程中，我发现有很多团队的 idea 也都特别好，但是他们展示的时间安排的不合理，有些项目花在讲 PPT 的时间太多了，导致最后没时间进行 demo，不做 demo 大家很难有直观的认识，影响了得分。\n\n## Q：今年的 Hackathon 只有 24 小时的时间来做项目，Mods 可以分享一些你们在比赛过程中有遇到一些什么困难以及是如何解决的？\n\n**Mods ：** 我们遇到最大的困难还是我们的硬件本身，我这块 RTX 2080 是前年买的，只有 8GB 的显存，新出的卡又很难买。而大批量数据的计算是要吃很多主存和显存的，8GB 显存处理 50GB 规模的数据还是稍微有些紧张的。这就迫使我们去绞尽脑汁想一些对显存使用比较经济的算法。\n\n![5](https://img1.www.pingcap.com/prod/5_3f45788abf.png)\n\n比如 TPCH q17，经过 TiDB 优化之后的 plan 中会有一个对 lineitem 表（最大的表）做一个 aggregate。我们原始的 aggregate 实现中会直接把这个大表所需要的列全部加载到显存，一次性完成 aggregate，这样实现起来很快，效率也最高。但是因为我们的硬件只有 8GB 显存，而 aggregate 之前的大表数据已经占用了 6GB 显存，后面进行 aggregate 计算所需要的资源就不够了。所以我们被迫使用了分桶的方法，将 aggregate 之前的数据预先分好桶，然后每个桶分别计算 aggregate，技术上很简单，但需要一些相对比较烦琐的编程及调参，另外效率上也不及一次性算完。最后我们分了 16 个桶才把这个 aggregate 算出来。\n\n另外一个就是编程语言的问题。TiDB 是用 Go 语言实现的，而我们这个项目因为要使用 CUDA，因此只能使用 C/C++ 技术栈，把 Go 语言和 C/C++ 结合起来只能借助 Cgo。大量使用 Cgo 会带来很大的编程负担，好在我们有了分层的设计和中间一套简洁优雅的 API，Cgo 只需要在 API 层使用，极大的减小了这部分负担。另外，Go 和 C/C++ 的最大的区别在于 Go 是 GC 语言，而 C/C++ 是没有 GC 的，需要手动管理内存，对于需要使用大量内存处理大批数据，同时对显存的使用又必须非常精细的这样一个项目，两边对象的生命期管理就成为一个很大的挑战。但也因为有这样一个强力的约束，倒逼我们去更加仔细的编码和测试，从而完成最后的 demo。\n\n![6](https://img1.www.pingcap.com/prod/6_87d0da7284.png)\n\n![7](https://img1.www.pingcap.com/prod/7_e2768bbfed.png)\n\n在 TiDB 接 GPU 的过程中还有个困难就是两边的数据格式不太一样。一些 primitive 的 type 比如 Int、Float 之类的是可以直接兼容的，但是像 String、Date、Decimal 这些复杂类型就不是很容易兼容了，为了让 TPCH 能跑起来，我们对 String 类型在 TiDB 这边做了一定的修改使得它能兼容 GPU 的计算引擎，而 Date 类型则在 GPU 计算引擎那边兼容了 TiDB 的 Date 格式，相比 String 和 Date 这种只需要做小部分改动，Decimal 类型要兼容则困难了许多，由于时间实在有限，我们最后选择在生成 TPCH schema 的时候把 Decimal 类型替换成 Double 来绕过了这个问题（如果有足够多的时间能让我们完成 Decimal 类型的兼容的话，那 GPU 的加速应该还能更明显一点，这点也算是我们的一点遗憾吧。）\n\nTiDB 的生态很广，所选用的编程语言也非常庞杂：TiDB 是 Go，TiKV 是 Rust，TiFlash 是 C++，TiSpark 是 Java 和 Scala。徐指导是我认识的唯一一个这五门语言全都写过的 TiDB 开发者。\n\n## Q：刚刚说到了一些遗憾，那如果时间更充裕，有什么可以做的更好的？\n\n**Mods ：** 我们觉得比较遗憾的地方是因为时间有限，对 GPU 硬件利用率的调优还有一定的空间。从一开始，我们的设计就基于了这样一个假设：GPU 作为处理器的一个基本哲学是靠足够多的计算任务来 hide 单个任务的 latency，从而提高系统整体的吞吐率，于是我们可以通过增加 CPU 端的并发以增大 GPU 端单位时间内的任务量，从而提高 GPU 硬件的利用率。为此我们在框架层设计了可以支持 CPU 端任意并发的精细 pipeline 模型。\n\n然而在后期实验的时候，我们没有看到随着 CPU 端并发的增加，GPU 的利用率随之提高。我们考察的几个 GPU 的 profile 指标，包括 kernel / kernel overlap 和 kernel / memory overlap，都没有显著的变化。因为当时我们 demo 的几个 query 效果都已经比较理想了，时间也有限，就没有进一步研究这一块。后面有时间的话，可能会再做一些更加深入的 profiling。\n\n## Q：刚刚 Mods 团队分享了他们在过程中遇到的一些技术困难和遗憾，陈昱老师作为工程师有什么其它建议或者想要了解的更多细节吗？\n\n**云启资本陈昱：** 对，其实也是和显存相关的东西。做 GPU 计算的时候，需要把数据装载到显存里，但单块显卡的显存毕竟是有限的，是否能利用虚拟化的方法，把机器上的若干块板卡，甚至说其他机器的板卡，组成一块大的 GPU 虚拟板卡，这样就能有几乎无限的存储和算力来完成 GPU 计算任务。\n\n**Mods：** 大家对 GPU 的资源本身比较有限这一块基本形成共识了，对应的也出现了很多解决这类问题的方案，包括多个 GPU 互连，GPU 虚拟化，甚至是分布式的 GPU 集群这样的技术。我们也在持续关注这些领域，另外我们也认为未来这个几乎是一个必然的方向。\n\n## Q：Mods 团队获得了两个奖，陈昱老师对这个项目未来有什么期待与展望吗？\n\n**云启资本陈昱：** 希望他们赶快合并到 TiDB 的主代码库，这是最大的期许了。\n\n## Q：Mods 团队自己有什么期待？\n\n**Mods：** 我们肯定和陈昱老师的期待一样。不过后续产品化中的困难还有很多，包括数据类型不兼容，开发环境是否友好等等。虽然演示的 demo 效果很好，不过不管是软件、硬件，还是对整个 TiDB 生态上，还有很多需要克服的困难。这方面讨论后续肯定会继续推进。\n\n我们最喜欢 Hackthon 的地方就是你可以无拘无束的去 hack 一个 idea，通过 demo 来验证它。但后续产品化方面，就要很严肃的去讨论，这是产品成型的必然路径。我们当然希望能快速落地，也会朝这个方向去努力争取的。\n\n## Q：最后的彩蛋缓环节，请大家分享一下除了自己的项目外，最喜欢哪个项目？\n\n**云启资本陈昱：** 我觉得比较喜欢一个是拿第一名的 UDF 项目，还有另一个三等奖项目 zh.md。程序员是最不喜欢写文档的，任何能提高程序员生产文档的工具都很受欢迎。还有一个获得最佳人气奖的 TiFlink 我也很关注。\n\n**Mods 团队-孙若曦：** 只能说一个项目的话，那就是一等奖的团队 'or 0=0 or' 做的 UDF 项目。我觉得不管是从架构还是实现来看，都非常优雅，而且完成度很高，整个演示的过程也很令人愉悦，我个人非常喜欢。\n\n**Mods 团队-徐飞：** 我也很喜欢第一名做 UDF 的项目，而且之前我们做过存储过程相关的事情，知道会有哪些技术难点，但这个项目把这些问题都解决的非常优雅。\n\n>关于云启资本\n\n>云启资本成立于 2014 年，一直坚持专注于 To B 领域的早中期投资，围绕技术赋能产业升级，进行系统化布局，投资领域覆盖企业服务SaaS、产业数字化、智联设备、先进制造等行业，投资组合包括 360 数科 (NASDAQ: QFIN)、英科医疗（SZ: 300677)、一起写(被快手收购）、酷家乐、百布、PingCAP, Zilliz, 德风科技、冰鉴科技、XTransfer, 环世物流、找钢网、小胖熊、智齿科技、晓羊教育、擎朗智能、新石器、e 换电等近 100 家优秀创业公司。  \n\n点击查看更多 [TiDB Hackathon 2020 优秀项目分享](https://pingcap.com/zh/blog/?tag=TiDB%20Hackathon%202020)","date":"2021-02-23","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"gpu-to-speed-tidn-up","file":null,"relatedBlogs":[]},{"id":"Blogs_118","title":"TiKV + Flink = 最佳人气流批一体库｜TiDB Hackathon 2020 优秀项目分享","tags":["TiDB Hackathon 2020"],"category":{"name":"社区动态"},"summary":"本篇文章将介绍 TiFlink 团队赛前幕后的精彩故事。","body":"Flink 是一个低延迟、高吞吐、流批统一的大数据计算引擎，作为大数据处理领域最近冉冉升起的一颗新星，其针对数据流的分布式计算提供了数据分布、数据通信以及容错机制等功能，被普遍用于高实时性场景下的实时计算。2020 年 TiDB 与 Flink 正式开始合作，探索将 Flink 与 TiDB 结合的解决方案。令人开心的是，在今年 TiDB Hackathon 上我们就看到出现了 3 个基于 Flink 的项目。**其中，TiFlink 队伍的项目为 Flink 实现了更好的 TiKV Source、Sink 和 TiDB Catalog Reader，支持 Snapshot 读取和 Change Log 增量读取和 2 Phase Commit 写入，以实现在 TiDB 里快速创建 Materialized View 和在 Flink 里方便编写读写 TiKV 数据的批/流处理任务。** 该项目凭借超高的人气一举夺得本届大赛最佳人气奖。我们在赛后采访了 TiFlink 团队部分队员与评委李钰老师，邀请他们分享自己的 Hackathon 经验。\n\n## 项目背景：当 TiKV 遇上 Flink\n\n提起 TiFlink 项目的灵感，还得从队长张茄子去年在公司内部的尝试说起。他的公司有一些数据实时分析的需求，但原有的数据分析工具在单表查询时很快，一旦到 join 时就不是很好搞。当时这个项目最终没能在内部成功做出来，但想法一直都在，直到今年 Hackathon 期间，张茄子和队友们一起重新探讨了可能的方案。目前，TiDB/TiKV 提供的 Flink 集成和 Java 客户端具有如下缺陷：\n\n- Java 客户端不支持抓取 CDC 日志，使用 TiCDC 需要通过 Kafka 转发，比较笨重和繁琐，延迟较高；\n    \n- Flink 集成的 Source 只支持批量读入，不支持批流结合（即先批量读入，后拉取 CDC 日志进行增量更新）；\n    \n- Flink 集成的 Sink 尚不支持 TwoPhaseCommit 协议，正在开发中的版本只支持各个节点单独 TwoPhaseCommit ，不支持全局同步 TwoPhaseCommit 。\n    \n\n![1](https://img1.www.pingcap.com/prod/1_ceb4a97e60.png)\n\n张茄子观察到 Flink 有着很完善的系统，在 Flink 里有一个 Flink CDC connector，但是只有 MySQL 的，没有 TiDB 的。所以队员们就想借助这次比赛做出一个 TiDB 的 CDC connector，将其贡献到 Flink 和 TiDB 社区，这样就可以打通 TiDB 社区和 Flink 社区的合作，借助 TiKV + Flink 打造出一个 TiDB 的批流一体库。**这就是 TiFlink 的由来，通过它可以实现更好的 Flink 集成（Connector）以及提供物化视图（Materialized View）功能，显著提高 TiDB/TiKV 生态环境的 OLAP 能力。**\n\n## 项目设计：TiFlink 流批一体库诞生了\n\n在比赛中，为了将设想中的 TiFlink 流批一体库实现落地，队员们做出了一系列尝试：\n\n- 为 TiKV 的 Java 客户端添加直接拉取 CDC 日志的功能，从而为实现批流一体数据处理的 Flink Source 创造条件；\n    \n- 为 Flink 开发 TiKV 兼容批读取和增量读取的 DynamicTableSource ，实现不同隔离级别的读取功能；\n    \n- 为 Flink 开发兼容 TiKV 事务模型并支持 TwoPhaseCommit 接口的 DynamicTableSink ，实现跨节点（切片，Region）一致的数据写入；\n    \n- 在上述组件的基础上，尝试实现 TiDB 上基于 Flink 的物化视图功能。\n    \n\n![2](https://img1.www.pingcap.com/prod/2_d7ea5d10d0.jpg)\n\n经过紧张的开发，在比赛答辩中 TiFlink 终于初见雏形，并顺利通过 DEMO 演示，TiFlink 团队为 TiKV 写了一个 DynamicTableSource，让 Flink 直接读取 TiKV snapshot 数据以及 CDC 流式变更数据，同时支持了 DynamicTableSink，能让 Flink 通过 TiKV 事务的方式将数据重新写回到 TiKV 里面。**通过这种方式，让大数据处理在 TiDB 以及 Flink 之间高效的流转。同时，TiFlink 也构建了一个 global snapshot coordinator，可以让分布式执行的 Flink 任务在以 snapshot isolation 的强一致方式来维护物化视图。**\n\n## 因为 Hackathon 走到一起的 TiFlink\n\n令人惊讶的是，在比赛的短短几天时间里就能做出如此完备功能的 TiFlink，其 4 名队员可以说来自天南海北。队长张茄子来自全球领先的招聘网站 Indeed ，在日本做新项目孵化；乘蜗牛追乌龟本名徐哲，在大唐电信从事流媒体服务端研发，是多届天池大赛数据库比赛骨灰级获奖选手；jiangplus 在一家 AI 和算法驱动的药物研发公司 Xtalpi，从事内部云原生机器学习平台的构建工作；SteNicholas （蒋晓峰（子懿））则在阿里云 Apache Flink 做生态相关工作。若在平时，看似分属于不同行业不同地区的四人可能永远都不会产生任何联系，但出于同样对 Hackathon 的热爱，将他们串联到了一起。\n\nHackathon 对张茄子来说，最大的吸引是可以将自己的 idea 讲出来，同时能够认识到拥有各种各样 idea 的朋友，大家一起分享自己的想法是一件非常开心的事情。\n\nSteNicholas 认为 Hackathon 带来的最大收获莫过于可以用自己熟悉的 Flink 或 TiDB 做任何想做的事情，只要能把它实现，就是一件特别 cool 的事情。\n\n而对于队伍中年纪最小的徐哲而言， Hackathon 是一次开拓自己视野的好机会，不但可以看到其他队伍提出了一些自己从未想过的 idea ，还能逼着自己在很短的时间内完成一个非常有意思的点子，完成对自我的挑战。\n\n与以前参加过的 Hackathon 不同，TiDB Hackathon 以「∞」作为本次大赛主题，参赛队伍只要有创新的 idea ,都可以拿出来参赛，在两天的编程里疯狂 coding，将自己的 idea 落地分享。对四人来说，这样的机会怎能错过？\n\n在进行了一番探讨和交流后，张茄子和队友们决定将 TiKV + Flink 打造流批一体库作为自己的参赛项目。\n\n今年由于疫情原因，大家都通过线上方式进行远程协作， 2 人负责 Flink 开发工作，2 人负责 TiDB 开发工作，每隔几个小时便会沟通项目进度。队长张茄子认为对远程协作来说保持一定频次的沟通至关重要，需要确保每个人的工作内容都朝着同一个方向，不至于最后走歪。\n\nSteNicholas 作为 TiFlink 唯一到现场参赛的队员，还通过线上向其他队员做起了现场直播，引得大家直呼羡慕。对 Hackathon 来说不能一起面对面奋斗，始终是一件非常遗憾的事情，大家都表示如果明年继续参赛，希望还能够在现场相聚。\n\n评委李钰老师是来自 Apache Flink & Apache HBase 的 PMC，出于职业敏感，对 Flink 这类生态结合的项目特别关注：“ **今年与 Flink 相结合的项目一共有三个，有通过 Flink 给 TiDB 做联邦查询的、有用 Flink 做物化视图的，但我觉得与 Flink 集成最深的还是 TiFlink** 。比如他们做了一个原生的 Java 的 CDC，利用 Flink 本身机制实现物化视图的 Snapshot 的全局性。我个人觉得这些方面再往后走都具备落地的价值，这也是我最喜欢这个项目的原因。”\n\n在李钰看来，如果能将 TiDB 联邦查询的项目与 TiFlink 项目结合在一起，对用户而言会产生更好的效果。现在有很多业务场景既有实时计算大数据相关的需求，又有数据库查询的需求，在这种情况下，将 TiDB+Flink 联合起来形成解决方案非常具有实用价值。例如， Flink 其实可以直接给 TiDB 提供访问 Hive 的能力。如果你既想查一个数据库里的数据，又想查一个 Hive 里的数据，就可以通过 TiDB 的这种标准 SQL 查询实现，屏蔽掉底层复杂的细节，这对于客户而言是非常具有现实价值的方案。\n\n## 未来期待：找到初期用户\n\n2 天的比赛时间非常有限，队员们希望在未来几个月找到一些初期用户，在用户反馈中不断完善 TiFlink 项目。队员们对此都很期待：“毕竟我们自己的想法和用户的想法还是有很多不一样的地方，比如说在一些选型、设计上的问题，我们自己没有办法解答，需要知道对用户来说哪种方式比较方便使用。**理想情况下，我们当然希望这个项目可以变成 TiDB 的一部分 ，作为一个整体被 TiDB 的用户非常方便地使用起来。**”\n\n李钰老师特别补充道：“其实 Flink 也一直在提批流一体数仓，在用户有实时需求的情况下，批流一体数仓能够极大地节省整体 TCO 。类似的方案之前在阿里内部也有过一些技术实现，但 TiKV+Flink 是首次以开源解决方案的形式予以实现，这可以为广大用户提供更普惠的解决方案。”\n\n除了 TiFlink ，本届大赛中也涌现出不少令人激动的项目，除了自己的队伍，还有哪些是最感兴趣的呢？几位队员明显有着自己的偏爱：\n\n张茄子：“我比较喜欢的是几个大佬们做的那个 Index 的项目，非常具有想象力，把一些比较新的想法都融合进来了，我感觉这也是最有前景的项目之一。”\n\n徐哲：“我最感兴趣的是 UDF 和 TiGraph 两个队伍的项目。UDF 在演示期间的展示非常酷， TiGraph 在展示期间有一个和原生的 TiDB 的性能对比，效果也非常好。他们的项目都是非常实用的想法，最后都获得了奖项，说明大家对他们也非常认可。”\n\n## Hackathon 建议：参赛，享受比赛\n\n作为经常参加 Hackathon 的老手，队员们也给对 Hackathon 活动感兴趣的萌新们分享了一些个人经验：张茄子建议新人一定要大胆来参赛。很多参赛选手其实也有好的点子和想法，但是他不太敢来参赛，害怕在众人面前露怯。其实大可不必，即使最终答辩效果不好，被淘汰也没什么不好意思的。不要太执着于比赛成绩，享受比赛过程就好了。你可以在这个过程中学习到很多东西，这才是最重要的收获。此外，如果想取得好成绩的话，需要提前对 TiDB 和 TiKV 进行了解和学习，获奖队伍中有很多人都是社区中的长期贡献者，事先做一些准备会更有胜算。\n\n李钰老师认为 Hackathon 活动是一个锻炼人的好机会，对于技术人员而言非常具有价值。就像马拉松长跑一样，在平时纷繁复杂的工作之外给自己一个机会来发泄一下。**马拉松是一种对自我体力极限的锻炼， Hackathon 则是一个脑力上的锻炼。** 最简单的建议就是要先来参加，在参赛的过程中享受比赛。\n\n> 点击查看更多 [TiDB Hackathon 2020 优秀项目分享](https://pingcap.com/zh/blog/?tag=TiDB%20Hackathon%202020)","date":"2021-02-23","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"tikv-and-flink-is-best","file":null,"relatedBlogs":[]},{"id":"Blogs_192","title":"中文文档规范化，zh.md 来帮你！｜TiDB Hackathon 2020 优秀项目分享","tags":["TiDB Hackathon 2020"],"category":{"name":"社区动态"},"summary":"本篇文章将介绍 zh.md 团队赛前幕后的精彩故事。","body":"近日，由 TiDB 社区主办，专属于全球开发者与技术爱好者的顶级挑战赛事——TiDB Hackathon 2020 比赛圆满落幕。今年是 TiDB Hackathon 第四次举办，参赛队伍规模创历届之最，共有 45 支来自全球各地的队伍报名，首次实现全球联动。经过 2 天时间的极限挑战， 大赛涌现出不少令人激动的项目。**为了让更多朋友了解这些参赛团队背后的故事，我们将开启 TiDB Hackathon 2020 优秀项目分享系列，本次访谈我们邀请到了 zh.md 的两位队员：来自 Cisco 的研发工程师王鹏翰、来自 PingCAP I18N 团队的 Coco，以及 Hackathon 特邀评委：来自青云 QingCloud 的张雁飞老师，共同谈谈他们对于 zh.md 的看法。**\n\n这也是一次专业工程师 + Tech Writer + 用户的三方会谈，**希望通过本次访谈和思想碰撞，让大家对于中文技术文档的写作和自动化改进有全新的看法。**\n\n## 缘起：一份优雅的中文技术文档是怎样炼成的？\n\n谈及为什么会对 zh.md 格外关注时，评委老师张雁飞表示：**技术文档的规范化是吸引用户，树立品牌非常重要的一环。** 一份格式混乱、翻译参差不齐的文档会给产品大大减分。无论产品本身有多么优秀，技术文档这“最后一公里”对于用户的体验都是至关重要的。\n\nzh.md 的队长王鹏翰作为一个 OpenTelemetry 技术爱好者，翻译文档时发现许多中文文档翻译得参差不齐，格式混乱，就连 CNCF 老大哥 K8S 的技术文档，仅仅是“样式指南”中出现的格式问题就已经可以用令人头大来形容了。不好用的技术文档往往会把 open source 的软件变成一个 source open 却难以上手的软件。\n\n![1](https://img1.www.pingcap.com/prod/1_08ce231512.png)\n\n恰逢 TiDB Hackathon 2020 正在征集项目，王鹏翰想到 PingCAP 的文档在国内的开源领域是十分专业的。就算有专业的 Tech Writer 维护，做到风格的统一也不容易，PingCAP 是怎么做到的？仔细阅读之后，他找到了一份 PingCAP 维护的 30 多页的风格指南。这份风格指南非常详尽，给了他非常大的启发。但对于大多数人来说，逐字逐句地阅读一份风格指南成本过高，而且也难以记清其中的规则，因此自动化的文档工具就成为了一个值得探索的方向。\n\n王鹏翰有些激动，他参加过大大小小 20 多次的 Hackathon 比赛，他认为这个 idea 可以排得上前三名。\n\n## 动手：工程师 \\+ Tech Writer 一起出发\n\n**——那就行动起来吧。**\n\n王鹏翰很快通过社区与 PingCAP 文档风格指南的作者：PingCAP I18N 团队的 Coco 同学取得了联系。他们很快达成了共识：希望借 Hackathon 这个机会，让更多人认识到开源软件以及 2B 公司技术文档规范的重要性。\n\nCoco 作为项目的产品经理+测试，规划了或许是中文社区里第一份详尽的中文文档写作风格指南，和王鹏翰一起设计了或许是中文社区里第一个中文标点符号检测工具、第一个中英文混排排版检测与优化工具；并且在短时间内设计了测试方法，实现对文档问题的排查，检验了工具的能力。\n\n技术上，王鹏翰实现了一套中文文档分析与检测工具，基于 AST（抽象语法树）和分词，系统地对文档进行扫描与诊断，评估文档质量并对其进行优化和修复，并且基于文档分析结果，使用统计学/ NLP 等工具，辅助作者写出符合风格规范的文档，还可以使用第三方 API，对文本进行中英文错误检测。\n\n目前**针对纯文本的 linter**，主要有以下两种：\n\n- 文档格式的 linter，例如 remark.js、markdownlint 等工具\n    \n- 英文语言的 linter，着重在检测风格和拼写上，例如 vale、textlint 等工具\n\n相较于英文文档，中文文档的 linter 语法要复杂很多。当前市面上针对中文文档的 linter，还处于早期阶段，尚无成熟的方案。在此次 Hackathon 中，王鹏翰首先做了语境 -> 实例 -> 字的 AST，然后针对标点符号、中文词汇（重组回句子后进行分词）、英语词汇做跳链索引。**相较于利用正则表达式制定规则的传统方案，有数量级的性能提升，同时保证了高扩展性。**\n\n![2](https://img1.www.pingcap.com/prod/2_721f5347a2.png)\n\n专业 Tech Writer 与开源社区活跃贡献者联手打造的 zh.md 新鲜出炉，用 TiDB 的官方文档小试牛刀，居然发现了 600 多处拼写错误、5000 多处排版问题。\n\n**这个工作，没白做！**\n\n**关于项目的未来，他们希望这份工具可以继续改进，应用于更广阔的天地：**\n\nv0.1: pingcap/docs-cn 使用上 zh.md 工作流，优化文档质量。\\[基本完成✅\\]\n\nv1.0: PingCAP 旗下所有 repo 使用上 zh.md 工作流，优化文档质量。\n\nv1.x: 向 CNCF 推广，帮助 CNCF 项目的中文文档都使用上工作流，优化文档质量。\n\nv2.x: 提供 SaaS 服务，帮助各个技术公司的项目进行文档辅助协作，辅助翻译。帮助 2B 公司更好的文档本地化。\n\n## Hackathon：不止是一场比赛\n\n王鹏翰已经是一个 Hackathon 的老玩家了，这也是他第四次参加 TiDB Hackathon 了。\n\n![3](https://img1.www.pingcap.com/prod/3_341623375e.jpg)\n\n<div class=\"caption-center\">图为 2017、2019、2020 三届 TiDB Hackathon 的纪念 T 恤</div>\n\n在此期间他的角色不断转变——\n\n根据王鹏翰的描述，2017 年的“第 0 届” TiDB Hackathon 是在一个赞助商公司的小食堂里举办，只有四五十人参与。虽然条件略显简陋，但是在场的工程师用硬核干货的 Go 项目为 TiDB 后续的 Hackathon 打下了一个“硬核”的基调。对于他自己来说，这届 Hackathon 帮助他更好地掌握了当时还不是主流的 Go 语言，这让他能够轻易地上手 Kubernetes，参加云原生的生态，为以后的工作打下基础。\n\n2018 年他是一等奖项目 TiDB Batch and Streaming SQL（简称 TBSSQL）的一员，和崔秋、杜川两位“大腿”一起，扩展了 TiDB 的 SQL 引擎，支持用户以类似 StreamSQL 的语法将 Kafka, Pulsar 等外部数据源以流式表的方式接入 TiDB。赞叹于两位大佬能力的同时，他作为学习者，了解了 TiDB 的核心架构与运作原理。\n\n![4](https://img1.www.pingcap.com/prod/4_07096446af.png)\n\n<div class=\"caption-center\">2018 TiDB Hackathon 一等奖队伍 TiBoys 合影</div>\n\n2019 年的他已经可以独立运营项目了，他基于 TiDB Plugin Framework，为 TiDB 增加大量用户定制化的功能扩展方案，为 TiDB 添加类似于 MySQL UDF 的功能。他提到：“可以说是前几年的 Hackathon 给我的经验让我有能力在这一年开始独立的写一些基于 TiDB 的功能，给 TiDB 的代码一些贡献。”\n\n**TiDB Hackathon 2020 对他来说更是意义非凡。** 这一年的 Hackathon 中，他用一个能造福 TiDB 社区内外项目的 idea 获得了三等奖；他还让女朋友带领“鸽了爽”队也一起参加比赛，完成他去年对 Plugin Framework 实现未尽的探索。\n\n对王鹏翰来说，参加 Hackathon 算是对自己的一个总结，也是给自己的 idea 一个落地的机会。相比于其它许多 Hackathon 项目宣讲会的形式，TiDB Hackathon 更注重硬核的技术比拼，不仅看 idea 的好坏，更注重实现的效果。正如 PingCAP CTO 黄东旭开玩笑说的，PingCAP 是一家 Hackathon 驱动的公司。许多 Hackathon 中出彩的项目是会成为 TiDB 的分支，甚至合到 TiDB 的主分支去的。\n\n对 Coco 来说，这次 Hackathon 给了她一个 Tech Writer 以外的身份。怎样通过技术手段减少中文文档撰写的工作量、自动地诊断和优化技术文档，如何将一份 30 多页的风格指南抽象成具体的自动化需求……这些都是全新的体验。\n\n张雁飞老师则是第一次以评委的身份出席 TiDB Hackathon。选手们对技术的狂热追求也激发了他对代码的热情。比赛当天等待的过程中，他也对自己的 UDF 项目进行了重构优化，进行了一次自己的 Hackathon 探索。他更表示如果有机会，希望明年能够以选手的身份参与到活动中。\n\n另外此项目已经发布在了 [https://github.com/tidb-incubator/zh.md](https://github.com/tidb-incubator/zh.md \"https://github.com/tidb-incubator/zh.md\") 里面，欢迎大家点击前往体验！\n\n> 正如本届大赛的主题「∞」，希望 TiDB Hackathon 在比赛之外，能够给每一个人带来无限可能。  \n\n点击查看更多 [TiDB Hackathon 2020 优秀项目分享](https://pingcap.com/zh/blog/?tag=TiDB%20Hackathon%202020)","date":"2021-02-23","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"let-zhmd-to-help-you-standardizating-chinese-document","file":null,"relatedBlogs":[]},{"id":"Blogs_209","title":"基于 AWS 的一站式分布式数据库测试体系，简单易上手｜TiDB Hackathon 2020 优秀项目分享","tags":["TiDB Hackathon 2020"],"category":{"name":"社区动态"},"summary":"本篇文章将通过 Ti-Improve 团队与华创资本企业软件投资负责人谢佳的对话，揭秘团队赛前幕后的精彩故事。","body":"![Bannerr](https://img1.www.pingcap.com/prod/Bannerr_f01d523623.jpg)\n\nTi-Improve 作为截止报名前 1 小时才临时组建的团队，4 位同学周强、方祝和、赵一霖、李德竹分别在北京、上海、杭州三地，在本届 TiDB Hackathon 中他们远程协作，**在 24 小时内克服困难，借助 AWS 的全套设施，搭建一站式分布式数据库测试的基本框架，最终极大地减少测试成本，扩大测试的多样性。最终这个项目获得华创资本 — 最具市场潜力奖。**\n\n华创资本企业软件投资负责人谢佳对 Ti-Improve 团队高度赞赏，他认为， Ti-Improve 团队的项目，不仅在技术实现上提升了整体工程效率 ，同时在 TiDB 生态中也具备很强的商业潜力。借此契机，我们邀请谢佳与 Ti-Improve 团队的四位同学一起进行访谈，通过投资人与程序员的思维碰撞，探寻更多 Ti-Improve 的 TiDB Hackathon 2020 精彩之旅。\n\n## Q：Ti-Improve 的组队过程是怎样的？这个队名的由来有什么故事？\n\n**Ti-Improve ：** 我们团队是临时组成的，在截止报名前 1 小时才有了项目的想法并且找到另外三位同学组成了战队，由于时间太着急，我们就沿用了去年的队伍名称，也就是 Ti-Improve 。\n\n在团队里周强主要负责测试基础设施，方祝和是 TiFlash 的核心开发、赵一霖是 TiCDC 的核心人员、李德竹是 HTAP 的开发人员。在本次 Hackathon 报名时间截止的前 1 小时，各种机缘巧合下才临时组队，最终完成了自认为超过预期的项目。\n\n## Q：可以分享下做这个项目最初的灵感和契机是什么吗？\n\n**Ti-Improve ：** TiDB 本身设计就是云原生的，也希望在云上能够有比较好的运行，这也是后续重点发展的方向。因此，我们就想能不能在 hackathon 上做一个在云上很方便导入导出数据，弹性的测试体系相关的项目。\n\n通过一些简单的调研我们认为这个事情是可以做的，最终定下来希望把 AWS 中足够多的组件完全组合，比如 lambda 和 cloudformation 及 cloudwatch，再加上 pipeline ，成为一个特别强大的平台，我们可以随时随地做各种各样的测试，比如说把错误注入如 Chaos Mesh，Fuzzing 等等把所有东西都能很有机的组合起来。\n\n![1](https://img1.www.pingcap.com/prod/1_ff2f87eea4.png)\n\n我们也有一直做测试基础设施的同学，在做测试平台的实际过程中也会遇到各类问题，调研了 AWS 的这些组件，发现这些组件已经能很好的解决比如调试、编排、可观测性问题，是可以直接看到背后的效果。其实 TiDB 也一直面临着一个问题，我们虽然一直尽全力保证测试的案例足够多、足够广，但实际上，很难将整个 TiDB 质量的全景图全部展示出来。除了开发、测试外，我们还可以做 serverless TiDB，甚至做一些的其他的东西，比如与数据湖对接起来等。\n\n![2](https://img1.www.pingcap.com/prod/2_7ac5ff0e00.png)\n\n其实 Hackathon 结束之后，我们团队的小伙伴也在一起研究，后续还可以用 AWS 的基础设施做什么，我们也发现了另四五个新的东西，后续可以在 TiDB 上尝试与结合。我们最初的想法是考虑是否其可以全部在 AWS 上一步到位，我们自己不需要花太多精力去开发，从而使得整个开发、测试迭代更快。\n\n## Q：本次 Hackathon 共有 14 位评委，作为机构评委对 Ti-Improve 一直情有独钟，可以分享一下最喜欢这个团队哪一点，团队在比赛过程中给您留下什么深刻印象？\n\n**华创资本谢佳：** 这次 Hackathon 主要是线上协作，Ti-Improve 的 idea 本身就很吸引我。从我的角度来看，希望能尽量找到一些与另外 13 位技术评委们不同的角度，我想表达的是，有巧妙商业价值角度的创新也是一种 hacking，可能 Ti-Improve 不是最有技术难度的项目，但这个 idea 背后的商业意义我很认可。\n\n我认为非常宝贵的一点是在于它提升了customer adoption 的润滑度。比方说， AWS 上的客户想要使用 TiDB 产品，他们如何尽快的完成可用性测试，这个过程如果有可能尽量减少客户所花的时间和摩擦的话，将非常有利于客户把TiDB产品顺利使用起来，而 Ti-Improve 就是这样一个工具。其次，Ti-Improve 的技术特点也很好的实践了 Cloud Native 的理念，Cloud Native 的 customer experience 就应该是能够把公有云上的各种能力充分的调度协同起来。\n\n## Q：在这次比赛过程中，团队有遇到过什么比较大的技术困难？是如何解决的？\n\n**Ti-Improve ：** 我们所有人都没有想到的一个问题是在这次 Hackathon 中遇到最大的拦路虎是 AWS 的权限系统，由于 AWS 的权限系统非常复杂且庞大，是完全出乎意料的。与此同时，我们没有操作自己账号的权限，每操作一步就会碰到两到三个权限问题，需要逐一去解决权限问题，效率非常低。因此我们就去找相关负责人开通权限还碰到负责人请假，直到周六（活动当天）11点才彻底解决权限问题。这其实是我们遇到的最大问题，虽然不算技术问题，但是却在这个上面浪费了很长时间。\n\n## Q：从机构评委的角度看，为什么会选中这个项目？这个获奖项目的技术和现实意义是什么？\n\n**华创资本谢佳：** 这次我们一共有 40 多个项目，其实作为投资机构评委我选择起来是非常纠结的，因为很多项目我都非常喜欢，但最终只能选出一个项目，所以特别纠结。因此，我当时是把喜欢的项目分成三类价值，每一类下再按商业价值、技术难度、商业迫切性、提案准备完成度等综合考虑进行排序：\n\n**一、在 TiDB 生态中有机会独立产品化、商业化的项目；**\n\n**二、帮助 TiDB 在底层的稳定性和其它性能各方面有提升，对 TiDB 底层核心能力有长远意义的项目；**\n\n**三、对 TiDB 商业化 adoption 有加速、优化作用的项目；**\n\nTi-Improve 项目完全使用 AWS 的基础设施来进行 TiDB 的测试，我觉得属于第三类中很典型的，不仅解决了具体的技术问题，同时也十分具有商业价值。\n\n## Q：由于今年的 Hackathon 时间只有 24 个小时，Ti-Improve 还是在周五的晚上才组队成功，在这个过程中你们觉得会有什么遗憾吗？如果时间能更充裕的话还有哪些地方是可以提升的？\n\n**Ti-Improve ：** 我觉得如果时间充足的化，对我们来说有以下几个点是可以提升的：\n\n1）整个系统的体系可以搭建的更完善一些，Hackathon 属于吃螃蟹类型，相当于是给后面的测试体系的架构开了一条路，如果有更多的时间来完善的话，希望整个流程和细节能够更好的扩展和完善；\n\n2）在 PPT 和 Demo 展示上可以做的更好，如果一开始能够很快把前面的路走通的话，展示的 PPT 的和 Talk 能够有更多的时间准备可以做得更好；\n\n3）应该有更多的时间去做调研，甚至应该结合特别多的东西到整个测试体系平台，由于时间的问题我们其实当天都还在读很多文档，熟悉该如何使用，在初赛的时候看到有队伍对我们最后的 Demo 有期待，但是由于时间因素，最后只跑了一个基本的流程，没有做到更灵活、更炫，希望有更多的时间能把这个东西做得功能更全一点，更有想象力一点，这是最大的遗憾。\n\n## Q：Ti-Improve 这次获得了华创资本的最具市场潜力奖，谢佳老师对这个项目未来有什么展望与期待？\n\n**华创资本谢佳：** 刚刚说到遗憾，感觉应该有点 Rock Music，笑～\n\n对 Ti-Improve 的期待方面，我觉得顺着这个思路，确实可以做的事情还是蛮多的。期待看到 Ti-Improve 这个项目能更细化。另一方面，我理解 PingCAP 接下来很重要的一步是在主流的公有云 AWS 和 Google Cloud 等平台上能够有更好的用户场景和更好的客户案例出来。所以，我也期待 Ti-Improve 能够顺着它的思路把更多类似的功能完善形成体系，能够实际到客户那边用起来。\n\n## Q：Ti-Improve 对自己这个项目有什么未来的规划或者是期望吗？\n\n**Ti-Improve ：** 此前由于人力问题，有些基础测试设施是没有达到我们期待的，因此对于这次 Hackathon ，我们希望能够利用 AWS 把这部分短板完全补齐，从而节省的人力成本可以把更多事情做好。对于测试与测试体系方面，我们认为测试是非常重要的，作为一款非常硬核的基础软件，稳定性绝对是最重要的没有之一的。\n\n我们很期待这个事情以后能够真正的在公司里跑起来，对我们内部来说不仅极大的提高了效率，云上的测试也给我们提供了另外的新思路，以后都可以在云上去做测试，让人很期待。\n\n## Q：作为软件工程专业出身的投资人，并且对企业服务领域的投资很资深，谢佳老师是如何看待 Hackathon 这类活动的？\n\n**华创资本谢佳：** 我之前参加过一些非技术性的此类活动，但基本是想一个商业模式或者 idea，最后进行演讲展示，而不是最终可以 Run 起来的程序。所以决赛时候看到参赛选手们 Demo 的实际效果，我觉是非常有感染力和冲击力的。Hackathon 本身是一个偏即兴创造的过程，这种创新的发生是自底向上的，我非常喜欢这种自发性的创新形式。\n\n## Q：除了自己的项目（Ti-Improve）外，最喜欢哪个项目？\n\n**Ti-Improve 周强：** 我最喜欢的是 VR 的那个项目，名字叫滑滑蛋，让大家看起来特别爽。\n\n**Ti-Improve 方祝和：** 我印象里最喜欢的是做提高 Bug 修复效率的项目，团队名字叫 zhangyushao ，我觉得在产品的稳定性、质量提升上很有意义，我很看好这个项目。\n\n**Ti-Improve 李德竹：** 我最喜欢第一名的 'or 0=0 or' 项目，我觉得特别有想象力，把一个看似很传统的东西用在这里，然后很好的解决这个问题，我觉得这个思路真的非常赞，可以向他们学习。\n\n**Ti-Improve 赵一霖：** 我也是比较喜欢第一名的 'or 0=0 or' ，他吸引我的点是他用 WASM 去做的这件事儿，WASM 相关的技术栈其实我一直都有关注，但是我也没想到能结合 TiDB 实现 UDF。我觉得之后可以借鉴这种思路，是一个很好的方式。\n\n**华创资本谢佳：** 除了 Ti-Improve，我其实喜欢的项目还蛮多的，我最开始列出来有 12 个，像 Ti-Graph 团队我也蛮喜欢的，因为有些类型的数据分析确实更适合用图数据库的来解决，我觉得类似的创新也在 TiDB 生态当中开启了一些新的可能性。\n\n>关于华创资本\n\n>成立于 2006 年的华创资本专注于企业软件、前沿科技、生命科学、消费升级等领域的早期投资，并利用深厚的资源与经验帮助所投企业进行战略规划、业务拓展和团队组建。目前华创资本管理的人民币基金和美元基金合计 80 亿元人民币。代表投资项目包括：什么值得买（创业板: 300785）、每日优鲜、Wish（NASDAQ:WISH）、同盾科技、老虎证券（NASDAQ:TIGR）、Ezbuy（NASDAQ:LITB）、别样红（美团 HKEX:03690 收购）、才云科技（字节跳动收购）、小满科技（阿里巴巴 NYSE:BABA 收购）、PingCAP、深鉴科技（赛灵思 NASDAQ:XLNX 收购）、Airlango（美团 HKEX:03690收购）、Nreal、爱笔智能、蓝箭航天、华科精准、新格元、福贝生物、璧辰生物、应世生物等。  \n\n点击查看更多 [TiDB Hackathon 2020 优秀项目分享](https://pingcap.com/zh/blog/?tag=TiDB%20Hackathon%202020)","date":"2021-02-23","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"one-stop-distributed-database-testing-system-based-on-aws","file":null,"relatedBlogs":[]},{"id":"Blogs_57","title":"当 TiDB 遇到图数据库 | TiDB Hackathon 2020 优秀项目分享","tags":["TiDB Hackathon 2020"],"category":{"name":"社区动态"},"summary":"本篇文章将介绍 TiGraph 团队赛前幕后的精彩故事。","body":"新冠是当下沉重的话题，科技可以帮助我们去降低疫情造成的影响，比如在发现一个病例之后，常规的措施都是按照一个地区的粒度进行隔离，如果我们有更加强大的图数据分析引擎，完全可以把防疫这件事情做得更加精准和高效。\n\n首先，我们基于图数据库进行简单的建模：所有人都是这个图模型中的一个顶点，两个人接触之后，会生成一条联系，并新增一条对应的边。然后进行系统的快速实现：所有人都有微信或支付宝，我们在这个系统中新增一个顶点，当两个人接触距离小一个值时，可以通过两个人的坐标或者 NFC 感应来得到这个距离，小于某一个距离，我们就在系统中新增一个边，并记录两个顶点的接触时间。\n\n基于这个模型，当我们发现一个新冠病例之后，就可以利用图数据库进行分析，快速地（秒级）找出在指定时间内接触过的人进行隔离，为防控疫情节省大量的时间和人工成本。\n\n以上是图数据库在日常生活中的一个典型场景，图数据库是一个使用图结构进行语义查询的数据库，它使用节点、边和属性来表示和存储数据。Gartner 认为，图数据存储可以跨越数据孤岛、并有效地建模、探索和查询数据，图分析将在未来几年内高速增长，然而在关系型数据库（RDBMS）之上使用 SQL 查询实现相关分析有点不切实际。\n\n**真的是不切实际吗？请 TiGraph 给你一个全新的回答！**\n\n**在 TiDB Hackathon 2020 赛事中，TiGraph 项目在 TiDB 中实现了一套新的 Key-Value 编码来引入图模式，处理传统关系型数据库难以覆盖的图数据分析场景，并使得 TiDB 在四度人脉的计算性能提升 8700 倍，一举夺得本届赛事的二等奖。**\n\n## 精妙的架构实现\n\n在短短的 Hackathon 期间，要开发一个完整的图数据库显然不太可能，TiGraph 项目尝试验证在 TiDB 中无缝集成图模式：\n\n- 在 SQL 中扩展出一个让 DBA 一眼就能学会的图遍历语法\n\n- 同一个事务中操作图数据和关系型数据的能力\n\n- 将图遍历作为 SQL 子查询（反之亦然）\n\n- 对于 N 度人脉场景的性能对比\n\nTiGraph 的技术栈从上层到下层与 TiDB 是一致的，主要做的工作有两部分：第一部分是写入，在元数据管理方面新增了 TAG/EDGE 两个图的 Schema 类型，分别表示图的点和边，写入时如果发现写入对象的 Schema 是图的 TAG/EDGE 时，就用图数据的 KV 编码，然后就走 2PC 事务提交，这和 TiDB 的流程一模一样，没有区别。\n\n第二部分是读链路，目前主要新增了两个执行算子，一个是 GraphTagReader 算子，用于读取图数据的点的数据。另一个是 Traverse 算子，用于根据指定的边进行图的遍历。因为图计算里面包含三部分，图的遍历、子图匹配和图聚合，这次 Hackathon Demo 主要是做图的遍历，后面去落地这个项目的时候，还需要把子图匹配和图聚合这些算子也设计出来。\n\n##  震撼的性能表现\n\n因为时间有限，TiGraph 在 TiDB 里面仅实现了 Key-Value 的整套逻辑，没有时间在 TiKV 中再用 Rust 重新实现一次，所以采用 TiDB 内置用于跑测试的存储引擎 Unistore。对于数据规模的考虑，一开始计划生成 100w 顶点 + 4000w 边，发现只有 TiGraph 能跑出结果。这是由于没有使用生产级别的分布存储引擎 TiKV，而是选择用于跑单元测试的 Unistore，另外这也不是传统关系型数据库的优势场景，所以 TiDB 跑不出数据。\n\n![1](https://img1.www.pingcap.com/prod/1_4e3160846a.png)\n\n于是采用更小的数据集，在 10w 行数据 + 650w 条边的规模下，测试 N 度人脉场景下 TiDB + Unistore 与 TiGraph 的性能对比。从上图可以看到，TiGraph 可以跑完六度人脉的测试，但是 TiDB + Unistore 只能跑三度人脉，第四度人脉跑了 7 小时还没有出结果。**随着人脉度的增加，TiGraph 的性能提升越明显，二度人脉的性能提升 190 倍，三度人脉的性能提升 347 倍，四度人脉在有限的时间内没有跑出最终结果，估算至少可以提升 8700 多倍。** TiGraph 后期采用 TiKV 存储后，在海量的图数据规模下也能弹性扩容，再配合 Coprocessor 实现图数据的计算下推，TiGraph 的查询性能还能再进一步提升。\n\n## 难点攻克：TiDB 与图数据库的融合\n\n在同一个事务中处理图数据库和关系型数据，如果一个业务同时使用一个传统关系型数据库和图数据库，那么要在两个数据库中实现事务和强一致性，几乎是基本不可能完成的任务，但是通过 TiGraph 可以出色地完成。\n\n首先，要设计一套与 SQL 极具兼容性、优雅且高扩展的语法，以下是目前两个非常流行的图查询语法两度人脉的示例：\n\n![2](https://img1.www.pingcap.com/prod/2_fe468dffe8.png)\n\n在一套系统中，引入两套查询语法会让用户学习成本更高，经过两天的讨论和碰撞，最终确定了如下示例的图遍历语法：\n\n![3](https://img1.www.pingcap.com/prod/3_68b1e56643.png)\n\n我们将上面语句拆成两部分来看：\n\n1. SELECT … FROM... 语句的查询结果作为图遍历（TRAVERSE 子句） 的起点\n\n2. 在 TRAVERSE 子句中指定想要遍历的 EDGE (边)，使用图遍历查询起点的二度人脉\n\n如果我们使用目前的 SQL 语法(假设不做任何扩展)写出来大概是：\n\n![4](https://img1.www.pingcap.com/prod/4_ecbe376a2f.png)\n\n通过以上对比我们可以看出扩展后的语法是极具表达能力的，同时也非常 SQL-style，另一个好处是将图遍历的使用 TRAVERSE 子句表述后，就可以无缝和 TiDB 关系查询中的其他子句联合使用了，这样可以复用 TiDB 已有的执行算子和表达式等所有的计算能力，并且用户的学习成本也很低。比如我们可以直接复用 WHERE/ORDER BY/LIMIT 子句（在编上加上过滤条件，将图遍历（TRAVERSE 子句）的输出结果作为后面 ORDER BY LIMIT 子句的输入）：\n\n![5](https://img1.www.pingcap.com/prod/5_08bc104a80.png)\n\n因为 TiDB 中的算子都依赖于强 Schema 的设计，为了复用 TiDB 中这些算子，TiGraph 中的 TAG 和 EDGE 也是强 Schema 的，这样图计算相关算子输出的 Schema 就能和关系型算子的 Schema 完全兼容。TiDB 的上层算子并不需要知道底层是图还是关系型数据，只要在最底层把之前的 TableScan 算子换成 GraphScan ，对于上层来说，所有能力都是可以复用的。\n\n在 SQL 层面有一篇学术论文做了类似的研究，把 Stream 和 Batch 这两个试着用 SQL 去结合。**目前，学术界还没有把 Graph 和 RDBMS 语法结合在一起的，TiGraph 项目实现了三个方面的创新。**\n\n第一个方面是做出一套 SQL Style 的图遍历语法。第二个方面是事务能力，就是在同一个事务里面操作图和关系型数据的能力。按照以前的惯例，用户必须要使用一个图数据库加上一个关系型数据库才能解决实际问题，然而要在两个数据库之间达成强一致基本上是不可能完成的任务，现在 TiGraph 具备这个能力，这是非常有魅力的，后续像子查询只需要在易用性和性能层面做提升就好。\n\n第三个方面就是在 TiKV 里面实现两种不同的编码模型，一种是给关系型的表编码的，一种是给 Graph 编码的。为了避免混合存储在一个 KV 的引擎里面产生冲突，通过加一个 g 的前缀使得整个KV 在 Base 层面就完全隔离，互不影响。\n\n## TiGraph 场景探索\n\n除了上面提到的新冠防疫场景之外，**TiGraph 还将在金融反欺诈、社交网络、知识图谱等场景中发挥作用。**\n\n### 金融反欺诈\n\n所谓近朱者赤近墨者黑，通过用户的关系网络来检测其与风险节点的关联度，可识别出其风险程度并作为一个参考指标，比如某用户三度关系之内是否触黑（有时候看单个节点和单笔交易是很难发现问题的），利用 TiGraph 可以很好地进行关联度检测和分析：\n\n- 检测用户的多层社会关系是否符合正常的图谱特征，如果是孤立的子图则可能是假造的关系网络，该用户存在高风险（包括黑/灰名单、高风险评分节点）\n\n- 检测多层关系网络中是否包含高风险节点，比如二度触黑\n\n- 通过 Personal Rank、Page Rank 等算法计算关系网络中节点的风险评分\n\n对于有组织成规模的数字金融诈骗，TiGraph 可以从复杂网络中快速进行团伙分析，为诈骗阻断提供及时的判断依据。\n\n### 社交网络\n\n大家在使用 Linkedin 的时候，发现有一个侧栏显示你的二度和三度人脉，社交平台通过分析社交网络关系，来帮助你扩展人脉圈子。TiGraph 可以在社交网络里面用作一个计算 N 度人脉的系统，在此之外，还可以将这些社交网络与你的消费记录等信息进行联合，得到一些深层次的信息，进而来帮助社交平台的推荐系统提高转化率。TiGraph 可以打破数据之间的孤岛，建立隔离数据之间的连接，产生 1 + 1 > 2 的效果。\n\n### 知识图谱\n\n知识图谱是 Google 公司在 2012 年提出来的一个概念，可以通过一定方法把知识抽取和清洗出来，然后在图数据库中提供查询。搜索引擎只能告诉用户，查询的结果与哪些页面相关，用户需要肉眼在页面里找答案，而知识图谱可以直接把答案告诉用户。举个例子，TiGraph 能直接告诉你在《权力的游戏》中坦格利安家族的伊利亚丈夫的兄妹是谁，是不是很 Cool ？\n\n## 未来方向\n\n未来想在两个方面进行尝试。首先，关于 TiGraph 项目的实现想写一篇论文，主要的方向有两个：第一个是如何在目前已有的关系型数据库（TiDB）里面去集成图模式；另外一个是具体的语法，需要去证明图计算的三个算子。\n\n其次是 TiGraph 这个项目的工程落地，赛队小伙伴们希望能进一步做深度的开发和实现工作。主要任务就是在 TiKV 里面把这一套 Key-Value 编码实现，并在 TiKV 的 Coprocessor 中实现图计算下推，从而打通整个链路，让图查询可以直接复用 TiDB 已有的执行算子和表达式，图查询和关系型查询也可以无缝结合。\n\n## TiGraph 背后的小伙伴\n\nTiGraph 赛队的三位小伙伴都具有比较扎实的技术功底，喜欢探讨和研究新的技术方向，其中两位都是 TiDB 社区顶级的开发者（pingcap/tidb Contributors）：crazycs520 这个 GitHub ID 虽然有点土，但是位列 TiDB Contributions 总榜 Top 5，wjhuang2016 同学也是一位天才选手。\n\n在 TiDB Hackathon 2020 期间，除了 TiGraph 项目之外，还诞生了很多前沿、有趣的项目，给 TiGraph 赛队小伙伴们留下了深刻的印象：\n\n- ' or 0=0 or ' 队伍的 UDF 实现非常优雅高效，也为这一部分的探索画上了一个句话，以后大概率没有人能做出更加好的 UDF 实现了，当然这也是为什么能拿第一名的原因。\n\n- B.A.D 的 VSC 扩展也是非常有创造性的，甚至在 Hachathon 期间已经发布到 VSC Market 并获得两位数下载。\n\n- GPU 加速计算打开了一个新世界的大门，对于 TPCH 中几个包含 JOIN Query 的性能提升是非常不可思议的。\n\n- T4 组由孙晓光老师 Team 做的 TTL Table 是另一个我非常喜欢的项目，极其实用。\n\n>TiDB Hackathon 2020 把小伙伴们天马行空的想法变成了现实，在获得成就感的同时多了一份感动，我们将重新出发，还有更多的惊喜值得期待！    ——TiGraph 队长 龙恒  \n\n点击查看更多 [TiDB Hackathon 2020 优秀项目分享](https://pingcap.com/zh/blog/?tag=TiDB%20Hackathon%202020)","date":"2021-02-02","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"when-tidb-meet-graph-database","file":null,"relatedBlogs":[]},{"id":"Blogs_148","title":"通过 WASM 实现优雅高效的 TiDB UDF","tags":["TiDB Hackathon 2020"],"category":{"name":"社区动态"},"summary":"本篇文章将介绍 ' or 0=0 or ' 团队赛前幕后的精彩故事。","body":"**本次大赛上， ' or 0=0 or ' 团队非常优雅高效地基于 WASM 实现了 TiDB 的用户自定义函数（UDF，User Defined Function）引擎，获得评委老师的一致高分，一举夺得本届大赛冠军，揽获 10 万元比赛奖金。** 为了给其他开发者们未来基于 TiDB 开发自己的应用和项目带来一些启示，我们在赛后采访了 ' or 0=0 or ' 团队与评委张东晖老师，邀请他们分享自己的 Hackathon 经验。\n\n## Hacker 精神的完美诠释\n\n如果不是技术极客的话，第一次见到 ' or 0=0 or ' 团队名（包含引号）肯定会比较懵。实际上，这个队名源自于 ' or 0=0 or ' 队员们一个恶搞的想法：想看看都 2021 年了，当这个名字被录入到各个系统时能不能搞点事情出来~\n\n![1](https://img1.www.pingcap.com/prod/1_523fcc6d9b.png)\n\n这个极富极客精神的团队有着 4 名队员，分别是庄天翼、朱贺天、王维真、施闻轩。他们分别是 TiKV 的 Committer、Reviewer、Active Contributor、Tech Leader，平常都是网友关系，通过参与 TiKV 或 TiDB 社区开发彼此相识。\n\n大赛评委之一的 TiDB 产品顾问张东晖老师对 ' or 0=0 or ' 的印象极深，给出了近乎满分的高分：“ ' or 0=0 or ' 在 Demo Show 的过程中给我留下两个特别深的印象：**一是队名本身就是 Hacker 精神的一种体现。同时，这个名字也点到了该项目最大的价值——安全，我认为这也是最难的地方；另一个是 Demo 的设计很漂亮，他们用讲故事的技巧，从一个最简单的事情到一个很惊人的性能，将观众一步步带到最高峰。**”\n\n作为参与过三届 TiDB Hackathon 的老队员，施闻轩认为 Hackathon 可以将平时一些不是特别成熟，甚至是不太靠谱的的设计和实践想法拿出来实现。如果放在平时，这些想法可能比较难以推进，但在 Hackathon 上可以自己组队拉人，通过代码证明它的价值，这也是 Hackathon 活动最有意思的地方。\n\n对于新人，闻轩建议创意其实可以不仅仅限于 TiDB、TiKV 内核产品，如调试工具、开发工具、可视化工具、与大数据方案的整合等周边生态工具，可以给大家发挥更广阔的想象空间。在最近两届 Hackathon 上，我们已经可以看到有越来越多高质量的周边生态项目出现，本届大赛中就涌现出不少基于 Flink 的项目。\n\n## 24 小时极限开发交付的完美 UDF\n\n**UDF 作为一款用户自定义函数引擎，可以让用户编写复杂的自定义函数执行逻辑，并在数据库上直接进行计算。** 这个能力可以使用户在 TiDB 平台上实现更多扩展，对一个平台产品而言，这是一个非常重要的事情。此前由于安全性等挑战， TiDB 一直没有推出 UDF 。而安全问题其实是一个特别困难的事情，可能投入研发一两年都搞不定。\n\n**令人惊讶的是， ' or 0=0 or ' 的 4 名队员在短短 24 小时之内，就将 UDF 这个项目做到了近乎落地产品的程度，包括整个下推、环境的准备、界面的接口设计都想得非常清楚，可以说已经是一个相当完美的项目。**\n\n![2](https://img1.www.pingcap.com/prod/2_060ab747be.png)\n\n以前 TiDB 不支持某些函数（如 bcrypt），通过 UDF 实现后，不需要将原始数据从 TiDB 捞回客户端计算。通过数据库本地分布式计算，可以显著提升性能，并无缝兼容 JOIN 等数据库功能。同时，通过 UDF 还可以请求云服务上的计算资源直接计算，例如执行云端人脸识别，执行 Serverless 负载实现无限伸缩等。\n\n![3](https://img1.www.pingcap.com/prod/3_5bc09e78c8.png)\n\n闻轩在采访中透露， ' or 0=0 or ' 之所以选择 UDF 这个方向。一方面是看到各种标准化测试都有 UDF 需求，但 TiDB 一直没有做，这被看作是一件非常困难的事情；另一方面，在 TiDB Cloud 的产品路线图上本就有一些对 UDF 的需求。两方面原因促使 ' or 0=0 or ' 选择这个非常具有挑战性的项目，最终，他们选择基于 WASM 来实现 UDF 。\n\nWASM 全称 WebAssembly ，是一个可移植、体积小、加载快并且兼容 Web 的全新格式。它最核心的能力就是安全，可以在一个平台上运行不可信任的代码，在经过互联网最严酷的安全环境考验后，WASM 已经是一个足够安全的技术。此外，WASM 还有一个特点是跨语言、跨平台，可以在浏览器、操作系统、云服务等平台运行，这使得开发者编程变得更容易，不受语言的限制。\n\n![4](https://img1.www.pingcap.com/prod/4_cfa721f64d.png)\n\n**对于 ' or 0=0 or ' 开发的这款 UDF ，东晖老师认为这个项目实际上是打开了一扇门，它让 TiDB 变成一个平台式的产品，让我们可以看到很多可能性。** 比如说通过这个项目可以进一步挖掘支持 TiDB 做 Machine Learning ，让 TiDB 支持 trigger 等等。未来甚至可以将其作为 TiDB 的核心功能，支持广泛的商业场景。\n\n## 遗憾\n\n24 小时的时间对于任何一个软件开发项目而言都是一种极限挑战，今年加上疫情原因， ' or 0=0 or ' 团队队员分散在北京、杭州等全国各地，项目推进全在线上展开，这也成为本届 Hackathon 面临的最大挑战。前几届比赛，队友们可以一起坐在办公室里，面对面进行沟通讨论。而通过远程方式协作是一种全新的体验，如何适应远程环境对所有队员来说都是一种新的考验。通过远程协作，4 名队员将要做的功能点进行切分，有的去负责 TiDB 侧的 WASM 怎么跑起来，有的负责 TiKV 侧的 WASM ，还有人研究 MySQL 兼容性，最后还要有人将这些代码合并连接起来。但在第一天各自分工写了一部分后，第二天在尝试合并的时候却发现怎么都合不起来。幸好在答辩前，在大家的通力合作下没有现场翻车。\n\n在谈及本次比赛有没有遗憾时，闻轩表示由于时间有限确实踩了不少坑。比如在规划中，他们本想在 UDF 中实现网络访问，但这个功能只在 TiKV 实现了，在 TiDB 却遇到了麻烦。由于在 TiDB 侧和 TiKV 侧调用的库不一样，在 TiKV 工作的部分 API 到了 TiDB 侧不能工作，网络访问这个功能最终没能跑起来；第二个遗憾是最初有一个同学安排了一整天时间尝试将 Java 跑在 WASM 上，将 Java 写的程序在这上面跑起来。但在研究了各种 Java 到 WASM 的方案后，都没有折腾出来，这个尝试也很可惜没有搞定。\n\n\n## 收获\n\n尝试并非毫无意义，通过各种尝试，他们已经基本探明可行性方案，只要再稍加时间就可以继续补充这些能力。对于 UDF 项目的未来，闻轩也充满期待：“除了我们自身的 24 小时高强度 Hacking 以外，UDF 项目的诞生也离不开辛苦筹备本次活动的 PingCAP 同事们的支持，以及连续十几小时倾听各组答辩的评委们的认可。Hackathon 已经结束了，**对于我们来说，如果未来我们设计实现的 WASM UDF 能合入 TiDB 产品主干分支，并成为一个真正能给用户使用的功能，将是对我们的设计和代码实现的最高认可**。”\n\n在采访的结尾，我们也想搞点事情——请 ' or 0=0 or ' 谈一谈本届大赛除自己之外有没有其他最喜欢的队伍，闻轩给出了森海飞霞的名字。他们做的项目是 dynamic copysets，解决了在比较大规模集群的情况下，如何显著提升整个集群的数据可靠性。这个项目本身来源于一篇论文，但在该论文中只提供了一种静态方案，如果要应用于 TiDB 的话，还需要做成一种 dynamic 的方案。这在学术界目前还没有解法，森海飞霞可能填补了学术界的空白，探索出一条证明确实可行的新方向。\n\n> 点击查看更多 [TiDB Hackathon 2020 优秀项目分享](https://pingcap.com/zh/blog/?tag=TiDB%20Hackathon%202020)","date":"2021-02-02","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"effective-tidb-udf-through-wasm","file":null,"relatedBlogs":[]},{"id":"Blogs_228","title":"神器 TiDE 在手，一键快速上车 TiDB | TiDB Hackathon 2020 优秀项目分享","tags":["TiDB Hackathon 2020"],"category":{"name":"社区动态"},"summary":"本篇文章将介绍 B.A.D 团队赛前幕后的精彩故事。","body":"社区开发者参与开发 TiDB 需要比较长的前期学习周期，其中除了复杂的编程语言外，另外一个最大的困难主要来自于项目本身的复杂度。作为一个多语言、多运行时组件的分布式项目，TiDB 的开发和调试门槛远远高于一些类似于移动端 App、Web 服务端、游戏客户端的常规软件项目。\n\n**B.A.D 团队的项目 TiDE 是一个基如今最流行的代码编辑器 Visual Studio Code 的 TiDB 插件，可以开发和本地/远程调试 TiDB 集群，让开发者不需要搞清楚 TiDB 的内部机制也能方便地在本地启动测试集群和实时调试编写，极大地提升了开发者开发和调试 TiDB 项目的体验。** 本项目在本次 TiDB Hackathon 2020 中一举夺得了二等奖与 CTO 特别奖两项殊荣。\n\n## 项目背景：一切要从 CTO 的一个 idea 说起\n\n大赛前一周，我司 CTO 黄东旭突然在群里说他有一个特厉害的 idea，这个想法起源于几周前，东旭本来想给 TiDB 加点功能，但是 TiDB 的代码太复杂，折腾了三天才把环境搭好，最后也没把代码写成。所以他想做个 VSCode 插件，有点类似脚手架，当开发者想加一个功能时，可以一键帮他把模板代码在 TiDB/TiKV/PD 组件中都直接生成出来，只需要自己往里面填充逻辑代码就行了。\n\n团队成员李逸龙从这个 idea 受到了启发，他发现 TiDB/TiKV/PD 的研发同学在日常开发时，需要自己手动替换服务器上的二进制和修改组件配置，重启后再手动去捞日志看结果，过程非常繁琐，同时在本地对各大组件同时进行 debug 单步调试也很复杂。他就想到能不能用 VSCode 插件把这些工作都自动化处理呢？类似 K8S 的 VSCode 插件，通过这个插件不用敲一行代码就可以管理 K8S 集群。于是研发工程师李逸龙、前端工程师黄宝灵和 K8S 专家吴叶磊三个人一拍即合，都觉得这个 idea 太好了，直击痛点！\n\n通过讨论，三个人大致确定了项目方向，**开发一个为 TiDB 开发者打造的一站式 IDE，提升效率的神器！**\n\n## 项目设计：做一个造福所有 TiDB 开发者的项目太有成就感了\n\n项目开发之初完全是原生态开发模式，大家一边实现自己擅长和最想做的部分，一边把想法记录下来列为 TODO。初步分工为宝灵哥负责实现脚手架及集群管理功能；阿磊负责调试功能的实现；小龙担任队长，负责产品及 K8S 部分功能的实现，同时他还是团队的灵感担当，不仅输出项目灵感，还根据三个人的 GitHub 首字母将团队取名为 B.A.D，很霸气的名字，全员好评。\n\n经过几天紧张且充实的发开，TiDE 终于初见雏形，它主要实现了以下几个重要功能：\n\n### 脚手架功能\n\n一键为 TiDB 生态中某个或某几个组件添加一项新功能，目前已经拥有一键为 TiDB Dashboard 添加一个 APP 的能力，添加之后用户只需要修改默认实现就能快速将自己想要的功能添加到 TiDB 生态当中。\n\n![1](https://img1.www.pingcap.com/prod/1_6fbf547f48.gif)\n\n<div class=\"caption-center\">为 TiDB Dashboard 添加一个新页面并实时预览</div>\n\n### 本地开发\n\nTiDB 生态是由多个项目构成的，很多功能的开发调试需要横跨多个项目，TiDE 能够一键将工作目录中各组件的代码编译打包并部署或更新到本地集群中，同时提供查看日志、拓扑管理、配置管理能力，让本地开发丝般顺滑。\n\n![2](https://img1.www.pingcap.com/prod/2_d7197359be.gif)\n\n<div class=\"caption-center\">从工作目录中的代码启动一个本地集群</div>\n\n### 远程开发\n\nTiDB 作为分布式系统，在分布式环境下进行远程开发也是很多场景下必不可少的能力。TiDE 提供了针对远程集群的一系列能力封装，包括集群启停，修改配置，替换本地编译的二进制到远端节点，查看日志，一键 SSH 到远程节点等操作。\n\n![3](https://img1.www.pingcap.com/prod/3_fde366b74a.gif)\n\n<div class=\"caption-center\">操作远程集群</div>\n\n![4](https://img1.www.pingcap.com/prod/4_e1ffc90764.gif)\n\n<div class=\"caption-center\">管理远程集群配置</div>\n\n### 调试 TiDB 集群\n\n包括调试本地集群和远程集群。同样遵循“TiDB 的典型开发运行模式是集群”这个思想，TiDE 能够一键对集群中所有组件启动单步断点调试，当然，调试单个组件或进程也能轻松搞定。\n\n![5](https://img1.www.pingcap.com/prod/5_fa283eabdd.gif)\n\n<div class=\"caption-center\">单步断点调试本地集群</div>\n\n### 「TiDE 确实好用，懂的都懂」\n\n项目开发的过程运用了边开发边推广策略，团队成员也表示参赛意图之一就是为了推广 TiDE，从而得到更多种子用户的反馈，再进而优化功能，在这其中也发生了几件意想不到的趣事。在 Hackathon 比赛现场，有一位友 team 的开发者遇到了 TiUP 的使用困难，在小龙的热心帮助下，使用 TiDE 解决了 TiUP 部署的权限问题，意外当场收获用户一枚，这位开发者在试用 TiDE 后不禁发出了感叹“ **TiDE 能提升我的开发效率，解放我的思路，确实好用，懂的都懂。**”\n\n![6](https://img1.www.pingcap.com/prod/6_35c82f2af0.png)\n\n几位成员还在项目答辩前将初版 Demo 给几位同事小小的剧透了一下，没想到把大家都震惊住了，直呼「这也太爽了吧！」，并且立即开始向团队成员提需求“诶，这个重启能不能支持一下只重启单个实例或单个组件呀？”，“诶，bench 功能能不能支持一下呢？”嗯，很合理，可以有，加到 TODO 里！看到大家的认可，B.A.D 的三位同学都表示非常开心，因为他们看到自己的项目确实是有价值的，做一个造福所有 TiDB 开发者的项目真的太有成就感了！\n\n![7](https://img1.www.pingcap.com/prod/7_ec94be2e2c.png)\n\n## 项目意义：功在当代，利在千秋\n\n「**功在当代，利在千秋**」是黄东旭对 TiDE 的评价，尤其对于 TiDB 这样一个拥有庞大并且活跃社区的开源项目来说，TiDE 的实现就是在为整个社区添砖加瓦。它不仅能反映到某一个产品上，而是能反映到未来和 TiDB 相关的所有产品上，具有极大的社会价值。具体项目意义可总结为以下两点：\n\n**降低 TiDB 的开发和调试门槛，从此上车 TiDB 不再困难。** 由于 TiDB 的代码非常复杂，让很多想学习或者想加入开源社区的小伙伴们望而却步，但有了 TiDE 这个神器后，大幅度降低了大家开发 TiDB 的门槛，让更多人能够快速上手 TiDB，融入社区。同时，小龙也表示 TiDE 有望替代开源项目中传统的文档先行吸纳成员的模式，传统开源社区一般是在项目首页放一些例子和文档来让人了解项目，而 TiDE 可以直接让用户快速上手操作，并且把文档里面死的内容变成交互式展现，迅速且直观的让用户了解到 TiDB 的各个功能，从而产生兴趣加入社区。\n\n**提高开发效率与用户体验，真正享受编程过程与结果。**有了 TiDE，我们再也不用把 90% 的时间花费在搭建环境上，而是让开发者们回归初心，尽情享受写代码快乐与编程的结果。阿磊也认为 TiDE 最大的意义就在于让更多的人目光聚焦到提升开发者体验上来。“在各类技术社区中，致力于提升开发者体验的小组相较之下往往显得不够关键也不够 sexy，甚至于我自己以前也有这样的成见。但 TiDE 打动了我自己，用实际效果告诉我提升开发者体验这件事空间极大并且能够做得非常有意思——我想这种启发是每一个使用过 TiDE 的人都能感受到的。”\n\n## 未来方向：Just a Beginning\n\n这届 Hackathon 虽然已经结束了，但对于 TiDE 来说，才刚刚是一个开始，TODO LIST 还很长，未来可以大致分为以下几个发展及优化方向：\n\n- **部署集群功能**：一键布署用于开发测试的各种类型集群\n\n- **机器管理**：管理用于布署集群的物理机或虚拟机\n\n- **TiUP 自动安装**：自动安装和升级 TiUP\n\n- **优化 TiDB 在 K8S 上的开发体验**：一键更新本地代码到 K8S 集群中并进行调试，让 K8S 上的开发流程如同本地一般简单轻松\n\n- **联动 UDF**：与本次 Hackathon第一名的项目 WASM UDF功能结合，提供脚手架和调试功能，轻松开发 TiDB UDF，让自定义 TiDB 功能变得轻而易举\n\n- **进入 TiDB Incubator Program**：一个好汉三个帮，如此好用的工具项目当然希望所有 TiDB 社区小伙伴参与进来，自己的痛点自己最清楚\n\n本次 Hackathon 之旅 TiDE 以揽得二等奖以及 CTO 特别奖两项大奖完美收官，在谈及本次参与黑客马拉松的感受时，三位成员也都表示收获满满：\n\n**黄宝灵：“** 非常开心的一次 Hackathon，尤其是我们的项目得到了大家的认可，帮大家解决了痛点。开阔了眼界，感觉大家都太强了。我们能同时收获两个大奖，也是特别地惊喜。”\n\n**吴叶磊：“** 兴奋、震撼和满足。兴奋于自己组的产品收到的认可与赞许，震撼于各种大胆又巧妙的 idea 和 Demo Show，满足于收获了两天深刻的回忆与一群新朋友（当然还有两个大奖！）。”\n\n**李逸龙：“** 收获了满满的 idea 和大家的热情，真的是神仙打架。比赛中展现的技术深度和广度都令人叹为观止，我觉得贵司不愧是 Hackathon Driven Company，这个传统一定要延续下去，毕竟中文开发者社区中很少见到过这么硬核的 Hackathon 比赛了。我们都非常享受比赛的过程，觉得与其说是比赛，更觉得是一个派对。同时也认识了非常多有趣的小伙伴，这就够了。”\n\n最后，[https://github.com/dragonly/ticode](https://github.com/dragonly/ticode)，目前已经在 GitHub 上收获了 46 颗星，在 VSCode 应用商店也有近 40 的下载量。\n\n![8](https://img1.www.pingcap.com/prod/8_804194886e.jpg)\n\n>TiDE 才刚刚开始，未来还很长，让我们一起期待  \n点击查看更多 [TiDB Hackathon 2020 优秀项目分享](https://pingcap.com/zh/blog/?tag=TiDB%20Hackathon%202020)","date":"2021-02-02","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"-tide-in-tidb","file":null,"relatedBlogs":[]},{"id":"Blogs_104","title":"感受开源的魅力，TiDB Committer 白珅的数据库探索之路","tags":["TiDB","Committer"],"category":{"name":"社区动态"},"summary":"今天我们就来看看 TiDB Committer 白珅的贡献历程吧~","body":"**Execution SIG 近日又喜提 Committer 一枚，他就是 b41sh 白珅。** 白珅同学毕业于上海交通大学电子与通信工程专业，曾就职于新浪、百度、爱奇艺等公司做视频系统和广告系统，现在在一家创业公司做多方安全计算，他的工作是开发存储引擎。在谈到是如何从业务开发转化为数据库开发，他说数据库一直是他想研究的方向，成为 TiDB Contributor 之后他对数据库和存储有了更多了解，正好面试官也了解 TiDB，从此便开启了数据库的探索之路。今天我们就来看看 TiDB Committer 白珅的贡献历程吧~\n\n![1-certificatebaikun](https://img1.www.pingcap.com/prod/1_certificatebaikun_827029cfdd.png)\n\n## 什么时候开始接触编程，有没有写过好玩的项目？\n\n我大概从 2010 年开始接触编程，后来写过一些小项目，主要在我们团队内部使用，是一个类似 Review Board 的 Code Review 系统，可以帮助你在提交代码之前进行 Review。\n\n## 如何了解到 TiDB？贡献 TiDB 感受如何？\n\n我比较喜欢关注知乎上的文章，有一次看到 TiDB 发了很多技术博客和源码阅读，觉得有很多干货内容，于是便关注了。后来也陆续参与了一些社区活动，像 TiDB Hackathon，可惜那时候对 TiDB 了解不多，所以没有做出比较满意的作品。\n\n我最早一次给 TiDB 提 PR 是 2019 年 3 月，当时改了一个小 bug，是 Executor 下面的时间处理函数，我觉得对新人很友好，上手比较简单。我和 PingCAP 的小伙伴张原嘉在 slack 上沟通比较多，他回复很及时，帮助我解决了很多问题，非常感谢他的帮助~\n\n## 贡献 TiDB 的动力是什么？\n\n我觉得数据库比较好玩，很有意思，贡献 TiDB 对我的就业和技术上都有比较大的帮助。虽然我用了很多年数据库，但不知道底层怎么实现的，之前对于数据库的了解都是浅层次的，在贡献 TiDB 之后解开了我很多疑惑。并且我看了很多业内 Paper 发现 NewSQL 是发展趋势，未来很多年内应该都会备受大家的关注，所以我也想多学习一些。\n\n## 贡献中遇到最大的困难是什么？\n\n数据库需要一些知识储备，当我做一些复杂的设计时会觉得知识储备不足，所以最近自己也在看一些数据库相关的书和 Paper，希望自己的知识积累更丰富一些，可以解决复杂并且有难度的 Issue。\n\n我遇到过最难的 Issue 是最近的 AggFunc Memory Trace， 需要追踪内存使用情况。\n\n![2-description](https://img1.www.pingcap.com/prod/2_description_d2e69284ce.png)\n\n这个 Issue 我做了实现方案的设计，具体功能由社区的同学完成，我和 mmyj 做了 Code Review，也是一件让我比较有成就感的事情。\n\n## 是否是个开源爱好者，有没有给其他项目贡献过？\n\n是的，我会留意和我工作相关的项目，最近比较关注 Apache Impala，也是一个数据库，还有像 CockroachDB、ClickHouse，但主要贡献还是在 TiDB。\n\n## 贡献中最有成就感的事是什么？\n\n最近性能竞赛 Review 了很多代码，帮助很多社区同学第一次做了贡献，尤其是有一个改了挺久才合并进去的 PR，挺有成就感的。看到他们就像感觉看到了当年的自己。\n\n![3-excutor](https://img1.www.pingcap.com/prod/3_excutor_a4f69fbf86.png)\n\n## 你认为开源是什么？\n\n我认为开源是一种生产关系，比较理想主义，**让很多不认识的人一起做一个产品，这种协作方式在其他地方是非常少见的，我很喜欢。**\n\n**随着 TiDB 社区逐渐壮大，TiDB repo 的 Contributor 也刚刚突破了 500 人，白珅同学在此送上他对社区的一段寄语：**\n\n很荣幸能够成为 TiDB 社区的 Committer 成员，在过去的一年多时间里，通过不断的为社区贡献代码，我学习到了很多前沿的数据库知识，也见证了 TiDB 社区的蓬勃发展。感谢社区小伙伴对我的帮助和指导，让我充分感受到了开源社区的魅力。希望未来有更多的人参与到社区的建设中，一起成长进步。","date":"2020-11-30","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"exploring-the-charming-of-opensource-tidb-committer-baikun","file":null,"relatedBlogs":[]},{"id":"Blogs_162","title":"TiDB Committer | 男友力 max 的典型工程师马钰杰","tags":["TiDB","Committer"],"category":{"name":"社区动态"},"summary":"本篇文章将介绍拥有多个身份的他成为了 TiDB 新晋 Committer:mmyj。","body":"他是第一期 Talent plan 的学员，也是第一期易用性挑战赛优秀参赛选手，拥有多个身份的他成为了 TiDB 新晋 Committer，他就是来自 Execution SIG 的马钰杰（mmyj）。\n\n他是游戏云玩家，也喜欢研究电子产品，总是第一时间入手，也逃不过第一时间吃灰。目前在星火网校做后台开发，工作中接触最多的语言是 Golang。他自称是个典型的程序员，但在采访的间隙突然让我稍等他一下，去给女友煮汤圆，着实让小编酸了一把～\n\n今天，让我们来看看 mmyj 在 TiDB 社区的心路历程吧！\n\n![1-certificate](https://img1.www.pingcap.com/prod/1_certificate_3e7bece0b0.jpeg)\n\n## 第一次贡献 TiDB，感受如何？\n\n2019 年 10 月，我第一次听说 TiDB，也是第一次接触到开源，之前并没有特别关注这个领域。因为公司使用 golang，所以我想找一些 golang 的项目学习，后来无意中在 GitHub 上发现了 TiDB 的文档和源码阅读活动，这让我参与社区得到了很大帮助。我还记得第一个 PR 是 execution 向量化的活动。\n\n![2-expression](https://img1.www.pingcap.com/prod/2_expression_89cc21a65d.png)\n\n当时觉得学习的门槛不高，正好那段时间有易用性挑战赛，就尝试参加了。\n最开始的时候会有点手足无措，不知道如何提交 PR 才能被采纳。不过社区小伙伴都很耐心，逐渐的我也就适应了贡献流程。\n\n## 为什么会持续给 TiDB 贡献？\n\n我在易用性挑战赛花了挺多时间，一下班八点多到家就开始做 issue。除了有周边可以兑换，我对 Reviewer 也很向往，觉得 Reviewer 是我努力的一个方向。我很感谢 Execution SIG 的 mentor 给了我很多帮助，我也希望自己可以反哺社区，像当时 mentor 们帮助我一样，指导社区的同学来贡献回馈社区。\n\n有一次我印象特别深刻，当时我有一个问题不太明白，立元就给我画白板来解释，可惜我当时太害羞，害怕麻烦他所以不好意思开摄像头，如果是现在我一定会更大胆的和导师交流。\n\n**TiDB 社区氛围很好，我希望可以把这份善意传递下去。**\n\n## 贡献过程中遇到过困难吗？中途是否想过放弃？\n\n有一个 PR 我断断续续做了很久，优化灵感的来源是一篇论文，我先花一个月时间看完了论文，然后再花一个月时间看 TiDB 代码，研究怎么修改才能达到论文的效果。难点在于，这个 PR 有很多优化的小点，把所有优化点都做完，整个战线就需要拉的很长。\n\n![3-pr](https://img1.www.pingcap.com/prod/3_pr_40a6da4308.png)\n\n在学习 Talent plan 课程的过程中也遇到了一些困难，因为课程的学习是在已知的框架内找一个未知的答案，对我来说是一个挺有挑战的事情。当时卡在优化器部分，不过最后我也没有寻求导师的帮助，自己去看 TiDB 源码找到了答案，感觉是有一点小作弊了哈哈。\n\n## 贡献过程中最有成就感的事？\n\n上面提到解决的最难的一个 PR 对执行器优化巨大，引入了滑动窗口的优化，提升了某些常用窗口函数的 10 倍计算效率。\n\n![4-executor](https://img1.www.pingcap.com/prod/4_executor_b9dcf1c79e.png)\n\n这个结果让我很满意，觉得自己的贡献很有意义。\n\n## 你认为开源是什么？\n\n很多项目只是把代码公开在 GitHub 上，我认为这并不能算是真正的开源，维护一个项目需要花费时间和精力，能像 TiDB 一样拥有一个活跃的社区，并且用心的去维护它，这很不容易。\n\n## 给 TiDB 社区新人们的一些建议？\n\n**一定不要害羞，社区的同学都很 nice！TiDB 社区期待你们的加入！**\n\n## 与 Contributor 同行，相信开放的力量\n\n随着越来越多的人了解和使用 TiDB，作为社区贡献者，我们选择了相信开放的力量，做自己真正喜爱和擅长的事情，与全球的开发者共同协作，打造我们梦想的数据库，帮助大家解决问题，让更多用户一起受益，在数据库历史的发展上留下自己的一笔，我们感到兴奋而且自豪！\n\n聚沙成塔，集腋成裘。社区每一个微小的贡献都让 TiDB 距离「数据库界的事实标准」更近一步。很荣幸能和一群志同道合的朋友一起做酷且正确的事情。\n\n在开源的世界，一切皆有可能。","date":"2020-11-30","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"tidb-committer-tipical-engineer-yujiema","file":null,"relatedBlogs":[]},{"id":"Blogs_213","title":"做一切为了好玩的极客，TiDB Committer 王贺的心路历程","tags":["TiDB","Committer"],"category":{"name":"社区动态"},"summary":"本篇文章将介绍王贺 TiDB Committer，DDL SIG 的 xhebox 的贡献之路。","body":"王贺看起来是一个不走寻常路的大三学生，从小就喜欢计算机，对于很多大学才开始接触编程的同学来说，高三就可以自己做一个 Linux 发行版无疑是同龄人中的佼佼者了。\n\n**今天就来了解一下 TiDB Committer，DDL SIG 的 xhebox 的贡献之路。**\n\n![1-certificatewanghe](https://img1.www.pingcap.com/prod/1_certificatewanghe_c7bfee8f11.jpeg)\n\n## 当时怎么想到要自己做一个 Linux 发行版呢？\n\n\n开始接触 Linux 的时候我觉得 glibc 太大了，下载下来有几十 MB 所以想换掉它。当时正好接触到了除了 glibc 以外的 libc，我就萌生了自己做发行版这个想法，甚至还想把 GNU 所有的东西都换掉，虽然最后失败了，但发行版还是做了下来。\n\n我从小就喜欢折腾这些东西，小学的时候用 Discuz 搭建过网站，高中时折腾苹果系统，这些都是因为兴趣所以自学的，也给我高三做 Linux 发行版打下了基础。我也是那个时候开始了解到 Go，我的 Linux 发行版的包管理器就是用 Go 写的，最近也开始在学习 Rust。\n\n## 你做的 linux 发行版现在可以下载到吗？\n\n以前是可以在 GitHub 上下载，现在不行了，我没有维护二进制包管理器，如果别人想用的话恐怕需要见到我本人，我可以用硬盘复制一份：）主要原因是维护二进制包非常耗时间，以前有 600 个包，现在被我削减到只有 300 个。我平时上课做实验也没有这么多时间， 几百个包都是手动编译，如果开源再维护，那可能没办法做其他事了。\n\n## 你是怎么和 TiDB 结缘的？\n\n第一次了解 TiDB 是 TCP 项目（Talent Challenge Program），在这之前我没有接触过数据库。有一天正好看到群里在发这个活动的信息，觉得挺有意思，不过这个活动需要 TiDB Contributor 才能参与，于是我就给 TiDB 提了一个 PR，在成为 Contributor 之后我就开始正式的加入了这个项目。\n\n## 参加过其他社区的活动吗？\n\n假期的时候我参加过快手的 KCode，主要比赛内容是读文件去计算 QPS。不过我参加完热身赛就不做了，到了决赛和半决赛会加一些限制，赛程后面比较偏向 IO 优化。我感觉我不是很擅长做竞赛或算法之类的比赛，更偏向学习和动手能力，所以更适合 TCP 这样的项目，自己发挥的空间更大。\n\n## 会经常给其他开源项目做贡献吗？\n\n有，不过其他项目的补丁比较散，不像 TCP 做了一个比较完整的功能。比如 musl libc 的兼容性不太好，我和使用 musl libc 的外国网友讨论过这个问题，也给 Google Chrome，Firefox 都提过补丁。\n\n##  贡献过程中遇到最困难的地方是什么？\n\n困难可能是因为从来没写过数据库，学校的数据库课程也才开始，教的也只是基本的 SQL 语句，所以我本身对 TiDB 和数据库也没什么了解，觉得入门比较难。\n\n## 从开源贡献中获得了什么？\n\n**协作经验**，之前虽然有共同协作的经历，但是没做过这么成熟的项目，并且有时候需要跨两个项目一起做开发。TiDB 的测试很完整，是我第一个提交的有完善 CI 的项目。之前提交的都比较传统，要么没有 CI，要么单元测试很薄弱，TiDB 是我接触的第一个有跨项目测试、集成测试的大型项目。\n\n## 贡献过程中最有成就感的事？\n\n有一次提 PR 主动推动了 PD 的进程，本来我只要给 TiDB 提就行，但当时项目的进度也需要 PD 那边的配合，我就给 PD 提了几个 PR。因为推动了 PD 并且在 DDL SIG 贡献，所以一个月就拿到了 PD 和 DDL 两个 Reviewer，还是挺有成就感的。\n\n另外我也通过了面试，拿到贵司的实习机会：）\n\n## 给 TiDB 社区的新人们一些建议\n\n贡献最开始的一段比较困难，可能刚进去社区还不熟悉流程，一定要坚持过去，就会豁然开朗。**在参与的过程中一定要 get hands dirty，观望不如动手，实践出真知。** \n\n## 对于本次 PingCAP D 轮融资，你作为社区的一份子，你怎么看？\n\n感觉很厉害，我听过的一些融资项目都不到一亿，PingCAP D 轮能融资到 2.7 亿美刀，都有点感觉不太真实了，而且还是开源项目。作为社区的一份子，这个事情还是挺让人有自豪感的，也有些认识的人给我发这个消息。\n\n**衷心希望 TiDB 社区越来越好！**","date":"2020-11-30","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"a-story-about-tidb-committer-wanghe-who-doing-anything-for-fun","file":null,"relatedBlogs":[]},{"id":"Blogs_266","title":"开发者 x 用户联手“打怪升级”，TiDB 易用性挑战赛& 4.0 捉“虫”竞赛完结！","tags":["TiDB 易用性挑战赛","TiDB 4.0 捉虫竞赛","社区动态","社区"],"category":{"name":"社区动态"},"summary":"所有参赛选手的点滴成果都已经汇聚到了 TiDB 产品中，TiDB 因你们的贡献而变得更好、更强大！","body":"2019 年 11 月，我们开启了“TiDB 挑战赛系列”比赛。[第一季性能挑战赛](https://pingcap.com/blog-cn/pcp-report-202002/) 结束后，参赛成员表示意犹未尽、围观同学蠢蠢欲动、社区小伙伴们热情似火，大家都迫切地想要为 TiDB 作出更多的贡献，让它跑得更远更稳。于是乎，年初我们又陆续开启了 [挑战赛第二季之易用性挑战赛](https://pingcap.com/community-cn/tidb-usability-challenge/) 和 [TiDB 4.0 捉“虫”竞赛](https://pingcap.com/blog-cn/tidb-bug-hunting-guide/)，**为 TiDB 全球开源社区的伙伴们提供一个竞技切磋的平台，同时也为推动 TiDB 的易用性、稳定性的提升注入新鲜力量。**\n\n目前两场比赛均于 5 月 30 日结赛，经过一周的代码审核和积分统计，积分排行榜的最终排名已经锁定，下面就带大家看看参赛选手们的累累硕果吧！\n\n## 易用性挑战赛\n\n让我们先来揭晓易用性挑战赛的排行榜：\n\n![1-易用性挑战赛排行榜](https://img1.www.pingcap.com/prod/1_9bbd2796f1.png)\n\n>完整积分榜见 [大赛官网](https://pingcap.com/community-cn/tidb-usability-challenge/)。\n\n本次大赛计入累计排名的参赛队伍基本信息如下*（按照比赛规则，有 PingCAP 人员参与的小组不计入挑战赛最终排名，即上图中有 TiDB Logo 标识的选手）*：\n\n*   总参赛人员：141\n\n*   总队伍数：102\n\n*   个人参赛者：87\n\n最终荣获前三名的优秀团队分别是：\n\n*   第一名（状元）：[.*](https://github.com/tidb-challenge-program/register/issues/7) (14499 积分)\n\n*   第二名（榜眼）：[gauss1314](https://github.com/tidb-challenge-program/register/issues/35) (11696 积分）\n\n*   第三名（探花）：[SSebo](https://github.com/tidb-challenge-program/register/issues/72) (5215 积分)\n\n除了以上三个优秀团队以外，我们看到本次大赛人才济济，吸引了众多优秀人才的加入，积分竞争尤其激烈，以下同学总共多的 4000+ 积分：\n\n*   [BABAIsWatchingYou](https://github.com/tidb-challenge-program/register/issues/15) (4560 积分)\n\n*   [qidelongdongqiang](https://github.com/tidb-challenge-program/register/issues/88) (4479 积分)\n\n*   [niedhui](https://github.com/tidb-challenge-program/register/issues/61) (4041 积分)\n\n除此以外也恭喜以下同学：\n\n*   Yisaer(TiDB) (4038 积分)\n\n*   [AngleNet](https://github.com/tidb-challenge-program/register/issues/13) (3409 积分)\n\n*   [Interesting](https://github.com/tidb-challenge-program/register/issues/4) (1880 积分)\n\n*   [Gallardot](https://github.com/tidb-challenge-program/register/issues/24) (1840 积分)\n\n*   [mantuliu](https://github.com/tidb-challenge-program/register/issues/26) (1836 积分)\n\n*   [STRRL](https://github.com/tidb-challenge-program/register/issues/33) (1755 积分)\n\n*   [zzh-wisdom](https://github.com/tidb-challenge-program/register/issues/30) (1644 积分)\n\n*   [□□□□□](https://github.com/tidb-challenge-program/register/issues/109) (1550 积分)\n\n*   [unsafe](https://github.com/tidb-challenge-program/register/issues/8) (1336 积分)\n\n*   [hawking&chacha](https://github.com/tidb-challenge-program/register/issues/31) (1300 积分)\n\n*   [oraluben](https://github.com/tidb-challenge-program/register/issues/11) (1086 积分)\n\n*   [ziyi-yan](https://github.com/tidb-challenge-program/register/issues/12) (550 积分)\n\n*   [hsqlu](https://github.com/tidb-challenge-program/register/issues/47) (550 积分)\n\n*   [blueshit](https://github.com/tidb-challenge-program/register/issues/45) (450 积分)\n\n*   [Rustin-Liu](https://github.com/tidb-challenge-program/register/issues/23) (400 积分)\n\n*   [imnotbigfacecat](https://github.com/tidb-challenge-program/register/issues/77) (400 积分)\n\n*   meow(TiDB) (350 积分)\n\n*   [走进新时代](https://github.com/tidb-challenge-program/register/issues/74) (300 积分)\n\n*   Hexilee (TiDB) (300 积分)\n\n*   [FoggyBottom](https://github.com/tidb-challenge-program/register/issues/75) (300 积分)\n\n*   [build](https://github.com/tidb-challenge-program/register/issues/44) (100 积分)\n\n*   [b41sh](https://github.com/tidb-challenge-program/register/issues/103) (100 积分)\n\n*   [bigger](https://github.com/tidb-challenge-program/register/issues/110) (100 积分)\n\n*   [psinghal20](https://github.com/tidb-challenge-program/register/issues/53) (100 积分)\n\n*   [Poytr1](https://github.com/tidb-challenge-program/register/issues/25) (100 积分)\n\n*   [SeaRise](https://github.com/tidb-challenge-program/register/issues/55) (80 积分)\n\n*   [krzysztofpioro](https://github.com/tidb-challenge-program/register/issues/63) (50 积分)\n\n*   [trabbart](https://github.com/tidb-challenge-program/register/issues/46) (50 积分)\n\n*   [SHUOSC](https://github.com/tidb-challenge-program/register/issues/113) (50 积分)\n\n*   [andrisak](https://github.com/tidb-challenge-program/register/issues/116) (50 积分)\n\n*   [Lifeistrange](https://github.com/tidb-challenge-program/register/issues/54) (50 积分)\n\n*   [zhang555](https://github.com/tidb-challenge-program/register/issues/6) (50 积分)\n\n*   fredchenbj(TiDB) (50 积分)\n\n*   [Beginner](https://github.com/tidb-challenge-program/register/issues/120) (50 积分)\n\n*   [Alex Chi](https://github.com/tidb-challenge-program/register/issues/125) (50 积分)\n\n*   [CopyAndSwap](https://github.com/tidb-challenge-program/register/issues/96) (50 积分)\n\n*   Tenzor(TiDB) (50 积分)\n\n*   [Hidehalo](https://github.com/tidb-challenge-program/register/issues/127) (50 积分)\n\n## TiDB 4.0 捉“虫”竞赛\n\n此次 [4.0 捉“虫”竞赛](https://pingcap.com/blog-cn/tidb-bug-hunting-guide/) 共有共有 40 位社区小伙伴组成 23 支队伍进行参赛。通过大家共同不懈的努力，一共为 TiDB 4.0 GA 找出 51 个 P1 级别的 bug 和 8 个 P0 级别 bug。下面先来看看大家的最终排名。\n\n![2-捉虫排行榜](https://img1.www.pingcap.com/prod/2_e88a62b4f3.png)\n\n获得前三名的参赛队伍依次为：\n\n*   第一名：Manuel Rigger，总分 11700\n\n*   第二名：wwar，总分 5950\n\n*   第三名：章鱼烧，总分 5850\n\n值得一提的是，本次 [捉“虫”竞赛](https://pingcap.com/blog-cn/tidb-bug-hunting-guide/) 第一名的获奖者 Manuel Rigger 是一位专攻数据库测试方向的博士后，来自苏黎世联邦理工学院，他的测试框架也帮助 MySQL，PostgreSQL，MariaDB 等找到 400 多个 bug。如果想更加了解他的框架是如何应用在 TiDB 的，可以报名参加 [TiDB DevCon 2020](https://pingcap.com/community-cn/devcon2020/)，他将在大会上带来精彩的分享。\n\n除此之外也恭喜以下几支参赛队伍：\n\n*   YKG，5500 分\n\n*   AndrewDi，4000 分\n\n*   cars，1700 分\n\n*   CHJ&navy，500 分\n\n*   jinxianqi，500 分\n\n*   North of community，500 分\n\n*   PingCAP，500 分\n\n*   xiaodong-ji，50 分\n\n**本次 [TiDB 易用性挑战赛](https://pingcap.com/blog-cn/TiDB-usability-challenge-program/) 和 [4.0 捉“虫”竞赛](https://pingcap.com/blog-cn/tidb-bug-hunting-guide/) 均设置了杰出贡献奖。在两个竞赛获得前三名的同学都将获得这个奖项。欢迎大家在 [TiDB DevCon 2020](https://pingcap.com/community-cn/devcon2020/) 与我们一起见证这个荣誉时刻！**\n\n在这次 [捉“虫”竞赛](https://pingcap.com/blog-cn/tidb-bug-hunting-guide/) 中，有几个 bug 引起了我们的注意：\n\n* [Server Panics when using partitions](https://github.com/tidb-challenge-program/bug-hunting-issue/issues/9)  这是 bug hunter **Rigger** 大神发现的 bug，查询导致 TiDB server 退出。\n\n* [TiDB 4.0 beta 在极高压力下有小概率发生请求无响应](https://github.com/tidb-challenge-program/bug-hunting-issue/issues/42)。**AndrewDi** 用他的独门测试场景帮助我们发现和反复重现了这个 bug。得益于他的帮助，我们在 RC2 中快速 fix 了这个很重要的稳定性问题。\n\n* [Dashboard](https://pingcap.com/blog-cn/tidb-4.0-tidb-dashboard/) 是 TiDB 在 4.0 中推出的提升易用性的功能，目前还处于内测阶段。**YKG** 在这次的大赛中，深度试用了 Dashboard 功能，提交了 5+ 的 bug。完善这些功能和解决这些易用性问题为我们继续提升 Dashboard 提供了有效的指引和巨大的帮助。\n\n**感谢所有参赛选手，你们的点滴成果都已经汇聚到了 [TiDB 4.0](https://pingcap.com/blog-cn/the-overview-of-tidb-4.0/) 的产品中，TiDB 因你们的贡献而变得更好、更强大！另外，所有的参赛选手们都可使用自己的积分兑换奖品哦，奖品设置详见活动官网（[易用性挑战赛官网](https://pingcap.com/blog-cn/TiDB-usability-challenge-program/) 和 [4.0 捉“虫”竞赛官网](https://pingcap.com/blog-cn/tidb-bug-hunting-guide/)）~**\n\n>本次 [TiDB 易用性挑战赛](https://pingcap.com/blog-cn/TiDB-usability-challenge-program/) 和 [4.0 捉“虫”竞赛](https://pingcap.com/blog-cn/tidb-bug-hunting-guide/) 已经结束，但 TiDB 追求一个完美数据库的脚步永不停歇，下一季赛季规划已经在路上了哦，敬请期待！","date":"2020-06-05","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"tidb-usability-challenge-program-and-bug-hunting-program-final-report","file":null,"relatedBlogs":[]},{"id":"Blogs_238","title":"TiKV Committer 聂殿辉：开源不仅仅是开放源代码，更是一种态度和沟通方式","tags":["社区","社区动态"],"category":{"name":"社区动态"},"summary":"“我对 TiDB 社区的整体印象用一句话概括就是：很专业，又很有人情味。”","body":">**聂殿辉**，TiKV Committer，曾经是一个连续创业者，目前在掌门科技游戏部门带一个研发团队。他还喜欢买手办，拼高达模型。他很少发朋友圈，几乎不用手机，自嘲是老年人生活模式，但对于参与社区还是保持着一片热情。\n\n## 有梦想，爱折腾\n\n我大学毕业一两年之后怀着一腔热血开始参与创业，当时是公司第三位员工。最开始我们做的一个项目想对标国外的 Twitter 和 Facebook，可惜没过多久微博就出现了，于是我们的项目渐渐退出市场。2013 年开始和另外一个同事参与过众筹方面的创业，也是由于时机不太好，后来也没有继续下去。\n\n技术人员看着内向，其实谈到技术就很好聊。压力比较大的反而是一些相关知识的疯狂补课。做众筹创业时项目偏金融，和股权相关，这方面我的知识有点脱节，为了更好的沟通因此恶补了大量金融领域的知识，这样才能和对方聊的比较顺利。\n\n创业压力确实很大，精神一直比较紧绷，有一种责任感在肩上。创业的时候不仅仅需要把自己的技术做好，还要去考虑自己做的东西是不是对社会有价值有帮助，同时也希望在这过程中对团队有成长和帮助，虽然最后创业没成功，但我对责任的理解更加深刻了。\n\n**但如果让我选择，我还是会去创业。创业的五年虽然很累但是很开心，有一些梦想和激情在，相信自己做的东西有价值。**\n\n所以我看 PingCAP 这样一个创业公司时，也别有一番感受。首先，我觉得 PingCAP 做开源有一种使命感，是我见过非常彻底的开源。从我知道 TiDB 开始你们就一直在开源方面做各种各样的尝试。同时也很重视技术输出，无论是相关数据库领域还是更外围的技术领域，都能看到你们在努力分享传授知识。\n\n其次还有一个很神奇的点，我在提 PR 的时候感觉 PingCAP 的同学上班时间都不一样，不同时间点都有人在 Review Code。\n\n## 玩转 TiDB 开源社区\n\n![1-github主页](https://img1.www.pingcap.com/prod/1_github_d1bbb7a9d9.png)\n\n### 对开源的理解\n\n之前工作中就使用过一些小的开源项目。TiKV 是我参与的第一个真正的大型开源项目。\n\n**我认为开源不仅仅是在技术上开放源代码，更是一个分享的态度、一种沟通方式**。之前我会读别人的源码，后来看了《大教堂与集市》，我才开始思考原来开源是这样的。开源项目和公司内部开发会很不一样，像 Linux 组织好一群人，用很好的沟通方式把一件事做好，才是很有意思的事情。\n\nTiDB 给我感觉很像集市的开发，把很多人聚集在一起，又保证可控的质量。对社区的沟通能力和组织能力是一个很大的考验。\n\n### 第一次接触 TiKV\n\n我的工作要求我对技术涉猎比较广，因为怕落伍所以我每年会了解一个开发语言。2018 年正好了解到 Rust，后来发现 Rust 确实不错，想更深入了解，所以要找一个项目去入手。后来在 GitHub 上扫到了 TiKV 这个项目，就开始去慢慢了解。\n\nTiKV 是一个很复杂的系统，涉及的东西很多，所以当时想找到一个切入点去参与，刚好那段时间 Coprocessor 在做函数下推，这个模块相对独立，对我来说只要了解一部分就可以参与 TiKV，很适合入手，issue 的描述和 lable 也很明确，比较好切入。\n\n之前创业做项目更看重功能的完备性、应用性，如果性能有问题可以回头再修改。但是给 TiKV 提 PR，很多是性能相关。性能在我之前的工作中不是最重要的，但因为 TiKV 太底层太核心，所以非常压榨性能，可能本身功能很简单，但很多都是性能上可以优化的点，这和我之前的工作方式很不一样。\n\n### 深度参与社区\n\n在参与 Coprocessor 之前我提过一个 PR，当时是 TiKV 有些依赖要升级版本，我那时对 Rust 还不了解，就想看看 TiKV 用了什么库，这样可以很快了解 Rust 生态。\n\n印象中解决的最难的问题应该是 Row Format，这个 PR 牵扯的东西比较多，中间会穿插着一些其他的事情要去做，有很多准备工作，并且需要很好理解整个 TiKV 工作流程，TiDB 上的数据发过来怎么存，怎么解码，都是比较细节的问题。\n\n**我对 TiDB 社区的整体印象用一句话概括就是：很专业，又很有人情味。**\n\n专业是因为社区很系统，活动很丰富，感觉 PingCAP 投入了非常大的精力在社区，像 [挑战赛](https://pingcap.com/blog-cn/TiDB-usability-challenge-program/)，[捉虫竞赛](https://pingcap.com/blog-cn/tidb-bug-hunting-guide/)，最近也被各种刷屏。我之前扫过你们的博客，信息量非常大。\n\n人情味是最开始看 TiKV  Review Guide，Review Guide 里提到一些规范，比如如果发现提 PR 的人掌握的知识不如你，也需要有一些耐心，让人觉得很专业又很有耐心。对参与者非常友好， Review 的环节很顺滑，对新手来说很容易有一个切入点。\n\n对人情味的感受还来自于一次面基的经历。\n\n有一天我突然收到 Breezewish( PingCAP 小伙伴）的信息：诶，看你 base 在上海，我也在上海，来线下面基呗？（直男就是这么直白）\n\n于是我们约在 PingCAP 上海办公室楼下的咖啡馆，Breezewish 给我很详细的讲了 TiKV 的模块，让我对 TiKV 了解又更多了些。再后来我一点一点写的函数被 Siddon Tang（PingCAP 首席架构师）发现，他说不要老写简单的啦，来写写难一些的呗。受此激励，慢慢开始上手做了一些阶梯的任务，比如 Row Format。后来也参与社区 [性能挑战赛](https://pingcap.com/blog-cn/pcp-report-202002/) 和 [易用性挑战赛](https://pingcap.com/blog-cn/TiDB-usability-challenge-program/)。\n\n![2-证书](https://img1.www.pingcap.com/prod/2_04142c81e7.jpg)\n\n从 Contributor 到 Reviewer 的进阶还是蛮轻松的，做的东西有认同感，到了 Committer 之后我会有一些压力，因为这个角色对项目的理解需要更深入，我也希望自己之后可以花更多时间去了解 TiKV。参与的越多，越觉得代码方面不是问题，对项目的整体把握才是最考验人的。\n\n## 趣味问答\n\n喜欢横屏还是竖屏？ **竖屏**\n\nEmac 还是 Vim？ **Vim**\n\nmac 还是 Linux？**Linux**\n\nFirefox 还是 Chrome？**Chrome，就是太吃内存了**\n\n喜欢用什么键盘？ **HHKB**\n\n鼠标还是触控？ **鼠标**\n\n甜豆花还是咸豆花？ **作为一个东北人当然吃咸豆花！**\n\n**最后回答一下庄天翼在 [上一个采访](https://pingcap.com/blog-cn/tikv-committer-zhuangtianyi/) 中的提问：你最喜欢吃什么菜，平时做菜吗？**\n\n我不喜欢吃肉，从记事开始就不太吃荤菜了，对吃的没啥欲望，平时也不做菜。老婆是个荒废厨艺的厨师，之前喜欢做菜，但在遇到我之后觉得做菜没有成就感了。（🤦‍♀🤦‍♂️）","date":"2020-05-12","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"tikv-committer-niedhui","file":null,"relatedBlogs":[]},{"id":"Blogs_185","title":"打造未来的数据库，不一定要写代码？ TiDB 4.0 捉“虫”竞赛等你来战","tags":["社区动态"],"category":{"name":"社区动态"},"summary":"赛程即将进入下半场，战况愈发激烈，我们总结了上半场的大事件快来看看吧~","body":"自 4.0  RC（Release Candidate）版本发布以来，大家已经迫不及待开始抢先体验。TiDB 4.0 包含了很多重要的、有潜力的特性：\n\n* TiUP 帮你更快的部署集群。\n\n* TiFlash 兼顾了 OLTP 和 OLAP。\n\n* 内置 DashBoard 大幅提高可用性。\n\n* BR 和 TiCDC 补齐了快速备份和增量数据变化的能力。\n\n* ……\n\n为了鼓励大家抢先体验 TiDB 4.0，加速 TiDB 4.0 正式版发版，捉虫竞赛应运而生。如今赛程过半，我们一起来回顾下当前赛况。\n\n## 国际友人开挂一支独秀\n\n捉虫大赛刚一公布，来自瑞士的 Mrigger 就火线加入，提交了多个 bug。强调下 Mrigger 肯定不是“托儿”。在 Mrigger 一波提交之后，有开发同学向 TiDB Robot 诉苦，「来者何人啊？周边礼品有点兜不住了！」。不查不知道，一查吓一跳，Mrigger 就是一位专业“碰瓷”选手。他已经为 SQLite 提交了超过 170+ bug，为 CockRoachDB 提交了 50+ bug。这位苏黎世理工大学的博士后研究方向是 RDBMS 的自动化测试，找 Bug 也是事半功倍。真可谓「天不怕地不怕，就怕测试开外挂」。\n\n**截止到发稿日，Mrigger 已经提交了 21 个 P1 bug，7 个 P2 bug，稳坐第一名的宝座。**\n\n## 开发者社区 护场子奋起直追\n\n在国际友人“砸场子”的时候，作为 TiDB Contributor，AndrewDi 坐不住了，他在 RC 发版后一周才开始测试，试用了 Sequence 之后，他信手拈来 2 个 bug，可见其内功之深厚。热身活动结束，AndrewDi 使出大杀器——场景测试。他开发了一套程序来暴力压测 TiDB，经过三天三夜的鏖战，TiDB 败下阵来，AndrewDi 也顺势提交了 3 个 P0 bug。\n\n**除了测出多个 bug，AndrewDi 还配合 PingCAPer 重现和定位 bug，让人真正感受到了纯粹的开源社区互动氛围。**\n\n截止发稿日，AndrewDi 坐上了捉虫竞赛的第三把交椅，同时还有更多开发者社区的小伙伴正在奋起直追，这股“较真”力量不可小觑哦～\n\n## 用户社区开辟第二战场\n\nAskTUG（asktug.com） 是 TiDB User Group 成员学习、分享的“聚集地”。自捉虫大赛正面战场 GitHub 开赛以来，已经有超过 50+ 的 bug report 在 AskTUG 上出现，涵盖 TiUP、TiFlash、Dashboard 等众多产品。\n\n![asktug](https://img1.www.pingcap.com/prod/1_asktug_36423eb042.png)\n\n（TiDB Robot 再次提醒下大家，4.0 捉虫大赛的任务积分可以兑换 PCTA 的考试资格，大家不如移步 GitHub 捞一波积分哦！）\n\n**大赛详情可以进入 [活动官网](https://pingcap.com/community-cn/tidb-bug-hunting/) 查看。**\n\n## 在社区贡献和支持下，发布 RC1 版本\n\n自捉虫大赛开赛以来，已有 13 个 team，24 名小伙伴报名参加了活动。我们在 GitHub 上收到了 66 个 issue，其中 58 个 issue 有效，有效率高达 88%。59 个 issue 中包含了 P0 issue 5 个，P1 issue 32 个，效率满满。目前排在积分榜的排名情况是：\n\n![asktug](https://img1.www.pingcap.com/prod/2_354ed8805a.png)\n\n**TiDB 开发者们作为追求完美的强迫症患者，从接到第一份 bug 报告后就开始了紧张的修复工作，终于在 4 月 28 日发布了 TiDB 4.0 RC1，修复了大量捉虫活动中发现的 bug。**\n\n也欢迎更多小伙伴加入到 4.0 捉虫比赛下半场，以下给参赛选手一些小 Tips：\n\n* 提前在活动官网阅读参赛细则，在 GitHub 按要求提交 bug issues。\n\n* 带压力的场景测试更容易发现 P0 级别的问题。建议小伙伴们可以用手头的压测程序狠狠的折磨 TiDB，加上一些故障注入更好，毕竟“大力出奇迹”。\n\n* 全链路测试。用上 TiFlash 和 BR 等工具，模拟生产环境做请求和备份恢复，可能有“奇效”。\n\n* 跨特性测试。例如，用 Partion 的时候，多关注下执行计划，也许当时开发功能的小伙伴就没有考虑到呢？","date":"2020-05-08","author":"舒科","fillInMethod":"writeDirectly","customUrl":"tidb-usability-challenge-program-situation","file":null,"relatedBlogs":[]},{"id":"Blogs_142","title":"赛程过半，谁在让 TiDB 变得更好用？","tags":["社区","社区动态","TiDB 易用性挑战赛"],"category":{"name":"社区动态"},"summary":"三月初，围绕着这 20 个呼声最高的需求，我们在社区启动了 TiDB 易用性挑战赛。赛事开启后，大家可是百花齐放，百家争鸣。目前赛程已经过半，我们先来看看战绩吧！","body":"随着越来越多的同学选择使用 TiDB， TiDB 的易用性收到越来越多用户的关注，让 TiDB 变得更好用就显得越来越重要。为了能够打造一个大家心中的真正好用易用的 TiDB，我们启动了 “[我的 TiDB 听我的](https://asktug.com/t/topic/2156)” 活动，并特意征求了 TiDB User Group(TUG) 专家组的意见，选择出了 20 个最重要、最迫切的易用性需求。\n\n三月初，围绕着这 20 个呼声最高的需求，我们在社区启动了 [TiDB 易用性挑战赛](https://pingcap.com/blog-cn/TiDB-usability-challenge-program/)。赛事开启后，大家可是百花齐放，百家争鸣。目前赛程已经过半，我们先来看看战绩吧！\n\n首先，我们看一下本次赛季参与的团队情况：\n\n![1-registers](https://img1.www.pingcap.com/prod/1_registers_399d6edb95.png)\n\n截止今日，我们一共收到 **93 支队伍**报名（包括个人参赛队员和多人组建团队），共计 **136 位选手参赛**。目前的积分排行榜上已有 5 支队伍积分超过 2000：\n\n![2-积分排行榜](https://img1.www.pingcap.com/prod/2_cb33666b3f.png)\n\n**目前个人参赛者成绩比较突出**，其中：\n\n* 状元：**gauss1314**（个人参赛者），针对 TiDB 进行了易用性优化。\n\n* 榜眼：**SSebo** （个人参赛者），针对 TiKV 进行了易用性优化。\n\n希望这两位同学能够再接再厉，争取突破语言和项目边界，能够同时造福多个 Repo，也希望其他团队也能早日超越这两位同学，咱也争个状元来玩玩\n\n最后，我们来看看本赛季整体任务完成情况：\n\n![3-整体任务情况](https://img1.www.pingcap.com/prod/3_d057c054ff.jpeg)\n\n如上图所示，蓝色表示被认领的任务数，红色的表示已经完成的任务数，也就是说，截止发稿时，**共有 215 个任务被认领，其中 93 个任务已经完成**。\n\n如此多的任务完成情况，还是让笔者十分惊喜的，要知道活动最初赛事组一共才给出了 20 个项目选项呢！下面我们一起来看看，截止目前拿分最多的项目：\n\n[UCP：Support the operation of adding multi-columns](https://github.com/pingcap/tidb/issues/5092)\n\n* 分数：2996\n\n* 团队：[gauss1314](https://github.com/gauss1314)（个人参赛者）\n\n* 仓库：TiDB\n\n* 该项目为 20 个迫切需求之一\n\n[UCP: Extract tidb_query into different workspaces](https://github.com/tikv/tikv/issues/5706)\n\n* 分数：2530\n\n* 团队：[SSebo](https://github.com/SSebo)（个人参赛者）\n\n* 仓库：TiKV\n\n[UCP: Support auto flush metrics](https://github.com/tikv/tikv/issues/7062)\n\n* 分数：2530\n\n* 团队：[BABAIsWatchingYou](https://github.com/tidb-challenge-program/register/issues/15)\n\n* 仓库：TiKV\n\n[UCP: Add WAL write duration metric](https://github.com/tikv/tikv/issues/6541)\n\n* 分数：1300\n\n* 团队：[hawking&chacha](https://github.com/tidb-challenge-program/register/issues/31)\n\n* 仓库：TiKV\n\n[UCP: Output slow logs to a dedicated file](https://github.com/tikv/tikv/issues/6735)\n\n* 分数：950\n\n* 团队：[.*](https://github.com/tidb-challenge-program/register/issues/7)\n\n* 仓库：TiKV\n\n[UCP: Support slow log in log searching](https://github.com/tikv/tikv/issues/7069)\n\n* 分数：605\n\n* 团队：[.*](https://github.com/tidb-challenge-program/register/issues/7)\n\n* 仓库：TiKV\n\n[UCP: Privilege check in statement summary tables](https://github.com/pingcap/tidb/issues/14889)\n\n* 分数：300\n\n* 团队：[blueshit](https://github.com/tidb-challenge-program/register/issues/45)\n\n* 仓库：TiDB\n\n[Limit the usage of storage in TiDB by total queries](https://github.com/pingcap/tidb/issues/13983)\n\n* 分数：300\n\n* 团队：[Yisaer](https://github.com/Yisaer)（个人参赛者）\n\n* 仓库：TiDB\n\n细心如你，可能已经发现，以上任务中，只有一个是在开赛给出的 20 个选项中的，也就是说，其他所有任务都是我们选手“自产自销”的哦。对于选手们的想象力和执行力，笔者大为惊叹的同时也是深深地佩服。赛事才过去一半，笔者不经好奇，接下去还会由多少的惊喜出现。\n\n最后，不管有没有上榜，大家都不要骄傲也不要灰心，稳住，下半场刚刚开场，还有大量高分项目等你来挑战，加油！\n\n---\n\nTiDB 易用性挑战赛 的任务分三个等级：Easy / Medium / Hard，每个任务对应一定的积分。这次我们优化了本赛季的分级赛制：如果你是第一次参与挑战赛的新人，Easy 的任务可以直接上手；而老玩家（在该 Repo 历史积分大于 200 分）则可直接挑战 Medium 及以上难度的任务！\n\n比赛结束后，选手可以用积分兑换丰富的奖品，除了 TiDB 限量周边（T 恤、帽衫、双肩包、办公室五件套、黑白游戏机充电宝、书签日历套装），还有 jetbrain toolbox 中任意一个软件的一年 license、PingCAP 年度大会荣誉席，甚至还有包机酒的硅谷之行！此外，完成任意一个任务的选手还可以得到“完赛纪念徽章”一枚。\n\n**报名方式：**\n\n发起 Issue 至 pingcap/tidb-challenge-program/register repo（通过【阅读原文】进入活动官网，点击“立即报名”即可快捷发起报名 issue）。\n\n欢迎大家加入 [TiDB Community Slack Workspace](https://tidbcommunity.slack.com/join/shared_invite/enQtNzc0MzI4ODExMDc4LWYwYmIzMjZkYzJiNDUxMmZlN2FiMGJkZjAyMzQ5NGU0NGY0NzI3NTYwMjAyNGQ1N2I2ZjAxNzc1OGUwYWM0NzE)，参赛过程中遇到任何问题都可以直接通过 **#tidb-challenge-program channel** 与我们取得联系。\n\n**延展阅读：**\n\n[Hi，你有一份 TiDB 易用性挑战赛「捞分指南」请查收](https://pingcap.com/blog-cn/tidb-usability-challenge-program-guide/)\n\n[TiDB 易用性挑战赛开启：解决用户的痛点，让 TiDB 更易用！](https://pingcap.com/blog-cn/TiDB-usability-challenge-program/)","date":"2020-04-23","author":"Shirly Wu","fillInMethod":"writeDirectly","customUrl":"tidb-usability-challenge-program-midterm","file":null,"relatedBlogs":[]},{"id":"Blogs_244","title":"左手尝鲜、右手周边？TiDB 4.0 捉“虫\"竞赛来袭！","tags":["社区","社区动态"],"category":{"name":"社区动态"},"summary":"邀请社区小伙伴参与一起为 TiDB 全球社区建设添砖加瓦，让 TiDB 新版本给大家带来更好的体验！","body":">[TiDB 4.0 RC 版本](https://pingcap.com/blog-cn/the-overview-of-tidb-4.0/) 已经发布，很多小伙伴已经跃跃欲试想要体验新功能了，这里有一个“一边体验一边拿周边”的好机会哦。\n\n**TiDB 4.0 捉“虫”竞赛来袭**，本次竞赛将持续到 5 月 30 日，邀请社区小伙伴参与一起为 TiDB 全球社区建设添砖加瓦，让 TiDB 新版本给大家带来更好的体验！我们将按大家发现的 bug 等级或提交的体验报告给予相应积分，积分可以兑换 TiDB 限量周边、PingCAP Education 培训机会等多项奖品。\n\n![](https://img1.www.pingcap.com/prod/1_tidb_bug_hunting_poster_b39e336be2.jpeg)\n\n## Highlights!\n\n**1.提交测试报告也可以获得积分**\n\n除了提交 bug 获得积分之外，我们也鼓励参赛选手提交测试报告，无论是哪一种贡献，都是可以获得相应积分奖励的哦。\n\t\n**2.丰富奖品**\n\nTUG 卫衣、蓝宝书、PCTA 考试券等。\n\t\n![](https://img1.www.pingcap.com/prod/2_list_of_prizes_e1be0fd028.jpeg)\n\n![](https://img1.www.pingcap.com/prod/3_list_of_prizes_f10331722c.png)\n\n**3.TiDB 挑战赛的彩蛋**\n\n现在 [TiDB 挑战赛](https://pingcap.com/blog-cn/TiDB-usability-challenge-program/) 的参赛选手现在也可以来 4.0 捉“虫”竞赛挖矿啦～挑战赛选手可以认领 4.0 捉“虫”竞赛 issue 中任何一个已经被标记为“challenge-program-2”的 issue，并按照挑战赛流程 pick up 即可认领任务。点击查看 [详细规则](https://github.com/pingcap/community/blob/master/bug-hunting-programs/bug-hunting-program-cn.md#彩蛋挑战赛挖矿)。\n\n## 4.0 捉“虫”竞赛报名\n\n**报名方式：**\n\n* 在 [bug-hunting-register 仓库](https://github.com/tidb-challenge-program/bug-hunting-register) 创建一个报名 Issue。\n\n* 报名 Issue 的标题统一为：\"bug hunting/sign up\"，内容需包括团队名称、队长的邮箱和团队成员的邮箱。注意个人参赛者也需要以团队的方式进行报名，个人参赛者只需要填写团队名和队长邮箱（即参赛者本人邮箱）即可。\n\n**团队参赛的注意事项：**\n\n* 包括队长在内，每队成员最多五人；\n\n* 我们非常欢迎参赛选手与 PingCAP 的成员进行组队参赛，每个队伍 PingCAP 的成员不超过 1 人。有 PingCAP 成员参与的团队将作为打星队伍，不参与积分最终排名，但仍保留积分兑换权限。\n\n* 如果在提 issue 过程中有任何问题欢迎加入**捉虫竞赛微信群**进行沟通交流。\n\n* 进群方式：添加 TiDB Robot（微信号：tidbai）为好友，回复“捉虫竞赛”即可入群。\n\n## 参赛流程\n\nTiDB 4.0 捉“虫”竞赛全流程包括：测试 feature->提交 bug/测试体验报告->评估 bug->获得积分->积分兑换，其中 “获得积分” 之前的步骤都将在 GitHub 上完成。\n\n**第一步：测试 feature**\n\n参赛队伍可以根据我们提供的操作手册自行测试，在遇到与操作手册结果不符合的情况可以上报 Bug，各个功能对应的操作手册可以在 [活动官网](https://pingcap.com/community-cn/tidb-bug-hunting/) 找到。\n\n**第二步：提交 Bug/测试体验报告**\n\n在测试完成后，如果参赛者发现了 Bug，则可以在 bug-hunting/issue 按照模版提交 Issue。\n\n参赛者在测试/试用之后，也可以记录下您的测试过程和体验感受，在 AskTUG（asktug.com） 上提交测试体验报告，该测试体验报告可作为 TUG MVA (Most Valuable Advocate) 内容贡献的参考依据，报告发布方式参见 [这篇文章](https://asktug.com/t/topic/33432) 。\n\n在 AskTUG 上提交的测试体验报告、经官方评定为**内容质量前三**的，会获得额外加分：第一名加 1000 分；第二名加 800 分，第三名加 500 分*（注：通过官方认可的体验报告均可获得 50 分）*。\n\n同时，伴随此次捉“虫”竞赛，TiDB 社区将成立 **SIG-Testing 专项兴趣小组**，小组成员可以持续为 TiDB 产品的质量保驾护航。**根据贡献程度的不同，小组成员将会在组内获得 Active Contributor 甚至 Committer 等社区荣誉**。\n\n**第三步：Bug 评估及积分授予**\n\nPingCAP QA 团队会根据 Bug 等级，为 Bug 打上 label（P0，P1，P2，P3）如果你是第一个发现 bug 的小伙伴，PingCAP QA 团队会根据 bug 的等级给你加上积分。如果经验证不是 bug，PingCAP QA 团队则会打上 label（non-bug）并关闭 issue，选手可以继续寻找其他 bug。\n\n**第四步：积分兑换**\n\n积分排行榜可以在活动官网查看。\n\n* **积分兑换时间**：每个赛季结束后一年内。\n\n\t例：第一赛季于 2020 年 4 月 30 日结束，兑换时间截止至 2021 年 4 月 30 日。\n\n* **兑换方式**：本赛季结束后填写礼品兑换表，工作人员将主动联系大家进行礼品兑换。\n\n## 学习资料\n\n在开始测试前可以阅读 [TiDB 官方用户文档](https://pingcap.com/docs-cn/stable/) 了解 TiDB。\n\n除此之外 [TiDB 社区伙伴们共同撰写的开源电子书《TiDB in Action》](https://pingcap.com/blog-cn/tidb-in-action-finish/) 也是很好的学习材料，书中包括了 TiDB 基本架构原理、最佳实践及案例、部署、运维（慢查询、热点问题调优）、备份恢复、数据同步和迁移等，可以作为参考资料，点击阅读 [电子书](https://book.tidb.io/)。\n\n>我们在捉虫竞赛等你来！进入 [活动官网](https://pingcap.com/community-cn/tidb-bug-hunting/) 了解更多比赛详情~","date":"2020-04-13","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"tidb-bug-hunting-guide","file":null,"relatedBlogs":[]},{"id":"Blogs_107","title":"TiKV Committer 庄天翼：只要能提升 Codebase 质量，就值得提交 PR","tags":["社区","社区动态"],"category":{"name":"社区动态"},"summary":"“参与社区贡献，除了增加了 Rust 使用经验和真正用于生产的数据库开发经验，同时也认识了很多人，扩大了社交圈，让我学到了很多东西。”","body":"2020 年 2 月，TiKV 项目迎来了一位新晋 Committer —— 庄天翼（GitHub ID：TennyZhuang），他 2018 年毕业于清华大学，目前在旷视科技担任分布式存储开发工程师，平时爱看动漫，工作之余也喜欢写一些代码，实现自己的想法。前天，我们“正儿八经”地采访了庄天翼同学，在互相努力憋笑中，愉快地掉落了以下文字……\n\n## 传说中的“天才少年”\n\n天翼并不是普通意义上的计算机“天才少年”。\n\n虽然他在大四时和队友一起拿了 CCPC（中国大学生程序设计竞赛）区域赛金牌，但他第一次接触编程已经是高中了，当时并没有深入研究编程，只是觉得学起来挺喜欢。在拿到化学竞赛金牌并保送清华后他也没有选择计算机专业，而是在材料学院就读，直到大三才正式转专业到了软件学院。\n\n为了顺利转系到软件学院，他利用课余时间修了大一和大二的计算机课程。得力于之前给学院老师留下的深刻印象，大三一开学他就成为软件学院的助教，协助老师设计课程并分享自己做这门课程的心得。\n\n**天翼说突破舒适区，学习新的东西是一件很有成就感的事。**\n\n“大三时学院有一门 Haskell 课程，当时作业分级，我完成了最高难度的题并且做了拓展，写了一个比较完整的 scheme 解释器，这门课拿了满分。虽然现在看来没那么厉害，但当时觉得很有成就感。”\n\n## 理解“开源社区”\n\n### 与开源结缘\n\n当被问到第一次是怎么接触到开源时，天翼笑了笑说“这要定义一下开源了，一开始是学习 Git 的使用，因为本科提交作业需要版本管理，接触了 Git。当时就想要不把代码公开上传 GitHub 吧，电脑万一坏了作业也不会丢。等我到高年级时有些自己的小项目被学弟发现竟然还有些 star，这可能算是我第一个开源项目吧。后来也陆续给一些其他小的开源项目做贡献，主要是自己平时会用到。”\n\n![](https://img1.www.pingcap.com/prod/1_github_contributions_5951cb9b87.jpeg)\n\n### 对“社区贡献”的理解\n\n天翼对社区的理解和我们不谋而合：**只要对 Codebase 的质量有提升，就值得去提交 PR**。\n\n“我之前给 Golang 提交过一个很小的 PR。当时我在调试 TiDB 的一个性能 regression 问题，感觉 Go 编译器在判断一个函数是否可以 inline 的调试日志里缺失了 cost 信息，于是我手动编译了 Go，在 debug 日志中添加了自己需要的信息来解决了我当时遇到的问题。很多人到这一步可能就结束了，但我还是将这行调试 log 作为一个 patch 提交给了 Golang。这个 PR 可能很小，但如果下一个 Go 开发者遇到了跟我相似的问题，也需要这行信息，他就可以省去自己完整编译一遍 Go 的时间，我觉得这就值得去提交一个 PR。我认为一个 PR 只要能提升 Codebase 的质量，就是对开源社区的贡献。”\n\n## TiDB 社区印象\n\n谈到对 TiDB 社区的整体印象，天翼说道，“**TiDB 社区建设是我见过开源项目中最好的。对任务的定义很明确并且每个组件都有明确的负责人。TiDB 社区对新人更友好，比如 issue 会标注难度，组建划分的很清楚，可以方便的找到适合自己的任务**。另外源码阅读系列比较有意义，我一般不看源码的实现细节，但源码阅读指南会让我更理解组件之间调用关系。”\n\n### 参与社区\n\n天翼是分布式存储工程师，对存储和数据库相关的项目比较感兴趣，因此 TiDB 是他参与的第一个比较正式的开源项目。当时 TiDB 还有若干篇教你“如何十分钟成为 Contributor” 的指南，于是就来试了一下。\n\n在工作中天翼用  Go 比较多，大概是三四年前他就有接触过 Rust 了，当时就觉得这个语言设计得非常优美，但因为一直没有工程实践所以看完书之后总是容易忘记。通过贡献 TiKV，天翼有了真正的生产经验，对 Rust 特性理解也更加深刻。\n\n**“对我来说，参与社区贡献，除了增加了 Rust 使用经验和真正用于生产的数据库开发经验，同时也认识了很多人，扩大了社交圈，让我学到了很多东西。”**\n\n他也很喜欢参与社区的活动，在 Infra Meetup 中担任过讲师，在两届 TiDB Hackathon 和 TiDB 挑战赛并都取得了优异的成绩，可以说是收获满满。\n\n对于 Hackathon 这样 48 小时的脑暴活动，天翼有一些小心得：“**无论拿不拿奖，idea 的实现很重要**”，比如在 2019 年的 TiDB Hackathon 上，天翼和队友完成的项目 [解决了跨数据中心场景下 TiDB 的 latency 问题](https://pingcap.com/blog-cn/geographic-data-distribution-traffic-and-latency-halved/)，使得跨地域 SQL 查询延迟下降 50%，跨节点消息数减半（即网络流量减半），实现上方法上主要从 Raft 层面来解决的，比较巧妙地提升了 Follower Read 的性能，并用 Follower Replication 减少带宽成本。这个项目获得了评审们和 TiDB 用户的好评，并且斩获了二等奖。\n\n### 感受最深的一个 PR\n\n天翼说在他成为 Committer 之前解决了一个很繁琐的 PR，改动了 80 多个文件 1000 多行代码。虽然难度不高，但令他印象十分深刻，“当时必须修改一个 TiDB 大部分模块都引用的公共接口，于是导致今天改完明天不合并，马上就冲突，给合并带来很大困难，我差一点就要放弃了，但又不甘心，于是我和 breezewish（PingCAP 的小伙伴）一起改动这个 PR 直到凌晨四点，PR 才通过单元测试，被 review 完。第二天上午就迅速合并了，避免了和别的 PR 产生冲突，这次合作印象很深。”\n\n### 进阶！进阶！\n\n从 Contributor 到 Committer，天翼在 TiDB 社区得到了成长和认可，对于如何晋升到社区下一个角色 Maintainer，他也有自己的想法。\n\n![](https://img1.www.pingcap.com/prod/2_certificate_of_recognition_d4f72ad1af.jpeg)\n\n“Maintainer 是一个要求比较高的角色。我觉得提多少 PR 或者 Review 多少 PR 都不是很关键。比如 孙晓光，他给 TiKV 提了一个独立设计的 feature，我认为这样才配得上一个 Maintainer。参与社区这个过程对我来说是很有意思的，可能在我贡献的过程中慢慢就会达到这个要求。”\n\n## 分享一个参加挑战赛的 Tip \n\n在访谈最后，作为 [第一季 TiDB 挑战赛](https://pingcap.com/blog-cn/pcp-report-202002/) 的第一名，天翼为大家分享了一个小 Tip：比赛过程中时刻和 Mentor 保持同步。\n\n“参加第一季时，我队友有一个 2000 分的 PR，写着写着废弃了，因为当时改动涉及的模块较多，且修改破坏了原本的分层设计最终没能合并。因此有接口设计变更随时和 Mentor 保持同步，及时达成一致意见，对大项目是非常重要的。如果涉及的模块较多，建议优先提交 RFC，经过多个 Reviewer 评审再开始具体工作。避免最后 Review 的时候对设计的理解有冲突而需要大量更改甚至不能合并。”\n\n（注：天翼所在的 .* Team 也参加了第二季 TiDB 挑战赛之易用性挑战赛，已经斩获了上千积分，想在积分排行榜上与天翼“过过招”的同学，可以看看这份“捞分指南”哦）\n\n>**最后在关麦之前……**\n>\n>我们请天翼对下一位采访嘉宾提一个问题。天翼说：“什么都可以问吗？” 我们：“对啊，反正不能露出的我们就会掐掉。”\n>\n>两个小时过后，天翼终于绞尽脑汁想出了一个问题：“**不知道下一位嘉宾平时做饭么，最喜欢吃哪道菜？**”\n>\n>行吧就它了（冷风吹过.gif ），话筒准备递给下一位嘉宾了！至于下一位嘉宾是谁，熟悉社区的小伙伴肯定都知道啦，先卖个关子，敬请期待～","date":"2020-03-18","author":"TiDB Robot","fillInMethod":"writeDirectly","customUrl":"tikv-committer-zhuangtianyi","file":null,"relatedBlogs":[]},{"id":"Blogs_40","title":"Hi，你有一份 TiDB 易用性挑战赛「捞分指南」请查收","tags":["社区","社区动态","TiDB 易用性挑战赛"],"category":{"name":"社区动态"},"summary":"我们简单总结了一些捞分技巧，希望能够帮助大家快速上手，追上这些排名靠前的参赛选手们。","body":"TiDB 挑战赛第二季之 [易用性挑战赛](https://mp.weixin.qq.com/s/VNtLhbOIJaAX2dEmjt8d5w) 已经开始一周了，由于有参加过上一季 [性能挑战赛](https://pingcap.com/blog-cn/pcp-report-202002/) 的老玩家强势加入，这一季挑战赛的竞争格外激烈，短短一周的时间，已有 3 支队伍获得了上千积分！\n\n![](https://img1.www.pingcap.com/prod/1_points_ranking_156f109f76.png)\n\n> 完整积分排行榜可以登陆 [活动官网](https://pingcap.com/community-cn/tidb-usability-challenge/) 查看。\n\n**战况简介：**\n\n* BABAIsWatchingYou Team 通过 [改进 Rust-Prometheus 中 Thread Local Metrics 的易用性](https://github.com/tikv/tikv/issues/7062) 获得 2530 分。\n\n* niedhui Team 通过 [为 TiDB-Dashboard 增加 TLS 支持](https://github.com/pingcap-incubator/tidb-dashboard/issues/87) 获得 1680 分。\n\n* hawking&chacha Team 通过 [为 RocksDB WAL 写延迟增加监控](https://github.com/tikv/tikv/issues/6541) 获得了 1300 分。\n\n* `.*` Team 通过 [使用单独的日志文件存储 TiKV 慢查询日志](https://github.com/tikv/tikv/issues/6735) 获得了 950 分。\n\n羡慕不如行动！我们也在这里简单分享一些捞分技巧，希望能够帮助大家快速上手，追上这些排名靠前的参赛选手们。\n\n## 捞分技巧 1：用户投票结果中排名前三的需求有高额加分！\n\n![](https://img1.www.pingcap.com/prod/2_demand_ranking_6233979f6a.png)\n\n为鼓励大家选择用户呼声更高的任务，本次挑战赛中用户投票排名前三的需求对应的任务，会在原有积分的基础上分别额外增加 10000、8000、6000 分。比如这个排名第三的需求：[record access statistics of databases, tables and indices](https://github.com/pingcap/tidb/issues/14998)，该需求原本的积分是 1294（积分低意味着难度低哟），再加上额外的 6000，这意味着完成这个低难度的任务总共能够获得 1294 + 6000 = 7294 分，性价比非常高！\n\n## 捞分技巧 2：Chaos Mesh Contributing Tutorial 可以帮助大家快速上手拿分\n\n[Chaos Mesh](https://github.com/pingcap/chaos-mesh) 是一款云原生的混沌测试平台，大家经常听说的 TiDB 混沌测试工具就是它。对了，Chaos Mesh 项目后续会有大惊喜哦，真 · 潜力股（只能剧透到此了，你懂的）。\n\n这份小小的 [Chaos Mesh Contributing Tutorial](https://yisaer.gitbook.io/chaos-mesh-contributing-tutorials/) 包含了 GitHub 协作基础、搭建 Chaos Mesh 开发环境和如何在 Chaos Mesh 中开发一个非常简单的新功能。内容不多，很快能看完。如果你之前没有参与过开源项目，可以看它；如果你有开源协作经验，但是没有参加过 Chaos Mesh 开发，也可以看它！看完小册子之后，大家就可以在 [Chaos Mesh 挑战赛题目合集](https://github.com/pingcap/chaos-mesh/projects/14) 轻松做任务、拿积分了！\n\n## 捞分技巧 3：如果觉得 Medium 题目太难，那就在多个 Repo 同时刷 Easy 题目\n\n相比第一季，这次易用性挑战赛除了 TiDB、TiKV、PD 之外，有更多代码仓库释放了任务：\n\n1.  [chaos-mesh](https://github.com/pingcap/chaos-mesh/projects/14)\n\n2.  [Data Migration](https://github.com/pingcap/dm/projects/1)\n\n3.  [Backup & Restore](https://github.com/pingcap/br/projects/1)\n\n4.  [client-rust](https://github.com/tikv/client-rust/projects/3)\n\n5.  [TiDB Dashboard](https://github.com/pingcap-incubator/tidb-dashboard/projects/17)\n\n6.  [cherry-bot](https://github.com/pingcap-incubator/cherry-bot/projects/1)\n\n7.  [TiDB Operator](https://github.com/pingcap/tidb-operator/projects/4)\n\n8.  [TiUP](https://github.com/pingcap-incubator/tiup)\n\n算上 TiDB、TiKV、PD 等总共有十多个代码仓库参赛。按照本次比赛规则，选手在每个仓库可以通过刷 Easy 难度的任务，获得最高 200 积分。那么 10 个代码仓库就是 2000 分，积少成多，收获非常可观哦！多多练手之后再挑战 Medium 难度的任务，也会更加轻松。\n\n## 捞分技巧 4：从一些比较简单的 Medium 任务突破\n\nTiDB：\n\n[通过 SQL 指纹的方式为 SQL 绑定执行计划 Hint](https://github.com/pingcap/tidb/issues/14987)：这是一个来自用户的需求，通过 SQL 指纹的方式能够极大简化创建 SQL Binding 语句的长度，提升用户体验。实现起来也并不复杂，修改 parser 文件支持语法后，再修改一下 TiDB 和创建 SQL Binding 相关的代码即可。\n\nTiKV：\n\n* [TiKV 日志和 RocksDB 日志统一管理](https://github.com/tikv/tikv/issues/6496)：将 RocksDB 的日志放在和 TiKV 的日志相同的目录，按照相同的方式 rotate，方便运维和查找。\n\n* [监控 TiKV 模块内存使用](https://github.com/tikv/tikv/issues/6717)：将几个核心模块的内存使用情况进行监控，方便排查 TiKV 内存问题。\n\nPD:\n\n* [PD API Swagger 支持](https://github.com/pingcap/pd/issues/2169)：让 API 符合 Swagger 标准且能生成在线 API 文档，实现简单，主要工作在于梳理  API，预期 3 天左右就可以完成。\n\n* [限制指定小表不被合并](https://github.com/pingcap/pd/issues/2171)：这是一个来自社区的需求，需要让某些 Region 能够不被合并。选手们完成这个功能后就能知道完整的 Region Merge 调度流程了，是一个非常有意义的功能。\n\nTiDB Operator：\n\n* [支持 Operator CRD Java SDK](https://github.com/pingcap/tidb-operator/issues/1575)：由于 TiDB Operator 是由 Golang 编写的，目前其 CRD 文件只有  Golang 客户端，这个任务将给 Operator CRD 创建 Java 客户端，对于扩展产品生态非常有意义。\n\n* [优化 Operator Controller 报错信息](https://github.com/pingcap/tidb-operator/issues/1936)：目前 Operator Controller 的报错信息不能帮助我们准确定位到具体的错误发生地点，这个任务将帮助我们优化 Operator Controller 的报错信息内容，提升用户体验。\n\nChaos Mesh：\n\n* [支持暂停混沌实验](https://github.com/pingcap/chaos-mesh/issues/294)：给每一个 Chaos 对象的定义中添加一个 Pause 的字段，如果被设置成 True，那么 Controllers 在每次调用到对应 Reconcile 逻辑时会取消掉已经注入的错误并且跳过正常的执行逻辑。\n\n* [拓展 NetworkChaos 支持限制网络带宽](https://github.com/pingcap/chaos-mesh/issues/303)：这个任务是对已有的 NetworkChaos 进行拓展，支持限制具体 Pods 的网络带宽，并且使用 [netlink](https://github.com/vishvananda/netlink) 工具包支持，这样可以很好的解决限制网络带宽的具体实现问题。\n\nTiDB Dashboard：\n\n* [日志搜索页面显示日志大小](https://github.com/pingcap-incubator/tidb-dashboard/issues/117)：前后端都要修改，但都改动不多，非常适合会写 Go 的全栈工程师。\n\n* [生成火焰图 SVG 时不依赖于 pprof 命令行](https://github.com/pingcap-incubator/tidb-dashboard/issues/90)：Dashboard 和 pprof 都是开源 Golang 项目，代码整合一下不算难。\n\n* [有 TiDB 节点不在线时重试 TiDB 请求](https://github.com/pingcap-incubator/tidb-dashboard/issues/131)：核心其实是用 Go 编写一个简单的 TCP 端口转发 + Health Check。\n\nData Migration：\n\n* [减少 DM 依赖的 TiDB 与 etcd 的日志输出](https://github.com/pingcap/dm/issues/495)：为依赖库设置一下 log level 就可以，花一天时间就能搞定这个任务。\n\n* [修复 remove-meta 的指定方式](https://github.com/pingcap/dm/issues/496)：将配置项修改为命令参数就能实现，性价比高。\n\nCherry Bot：\n\n* [将各 Repo 的配置分为不同文件](https://github.com/pingcap-incubator/cherry-bot/issues/3)：对 config 组件进行小幅改动就可以。\n\n* [多分支并行 auto merge](https://github.com/pingcap-incubator/cherry-bot/issues/4)：目前 PingCAP 多个开源项目（如 TiDB、TiKV 等）都在使用该功能自动 merge 经过 Reviewer 点赞的 PR。这个任务将完善这个功能，使其能够同时 merge 多个分支上的 PR。要完成它需要修改 auto merge 的主体逻辑，但因为代码模块比较独立，适合用来学习 bot。\n\nTiUP:\n\n* [给 Playground 添加集成测试](https://github.com/pingcap-incubator/tiup/issues/66)：只需要添加单元测试 case，对于了解代码逻辑非常有帮助。\n\n* [支持为 Playground 中的 TiDB/TiKV/PD 指定配置](https://github.com/pingcap-incubator/tiup/issues/64)：支持这个功能可以极大的提升 TiUP 的易用性。要完成该任务需要添加一些 flags，同时在没有指定配置时使用默认配置。\n\n* [给 Playground 组件集成 Grafana](https://github.com/pingcap-incubator/tiup/issues/63)：支持这个功能后，使用 Playground 部署的集群就有 Grafana 监控了！实现的时候可以参考集成 Prometheus。\n\nClient-rust:\n\n* [支持清理特定 key 的锁](https://github.com/tikv/client-rust/issues/111)：在事务冲突严重时，针对小事务只清理特定 key 的锁能大大减轻 TiKV 服务器的负担。\n\n* [为 PD 客户端添加 Region 缓存](https://github.com/tikv/client-rust/issues/114)：使用本地缓存的 Region 信息对于提升性能和降低 PD 服务器负担有很大的帮助。TiDB 中已经有比较成熟的实现，这里只需要将 TiDB 的实现迁移到 Rust 中。\n\n>不知道看完以上“捞分技巧”，大家有没有摩拳擦掌、准备上阵抢积分了？\n>\n>报名方式、参赛细则请看 [这篇文章](https://pingcap.com/blog-cn/TiDB-usability-challenge-program/)，同时也欢迎大家加入 [TiDB Community Slack Workspace](https://tidbcommunity.slack.com/join/shared_invite/enQtNzc0MzI4ODExMDc4LWYwYmIzMjZkYzJiNDUxMmZlN2FiMGJkZjAyMzQ5NGU0NGY0NzI3NTYwMjAyNGQ1N2I2ZjAxNzc1OGUwYWM0NzE)，在参赛过程中遇到任何问题，都可以直接通过 #tidb-challenge-program channel 与我们取得联系哦～","date":"2020-03-17","author":"张建","fillInMethod":"writeDirectly","customUrl":"tidb-usability-challenge-program-guide","file":null,"relatedBlogs":[]},{"id":"Blogs_83","title":"历时 48 小时，开源电子书《TiDB in Action》第一版完成！","tags":["社区","社区动态"],"category":{"name":"社区动态"},"summary":"从上周五晚 21:00 开始，历时 48 小时，共有 102 位来自社区的作者参与，截止周日 21:00，总计产生了 421 次 Commit，199 个 PR，最终开源电子书 <TiDB in Action> 第一版诞生。","body":"[TiDB Book Rush!](https://pingcap.com/blog-cn/tidb-book-rush-write-a-book-in-48-hours/) 从上周五晚 21:00 开始，历时 48 小时，共有 102 位来自社区的作者参与，截止周日 21:00，总计产生了 421 次 Commit，199 个 PR，最终开源电子书 《TiDB in Action》 第一版诞生 \n\n感谢社区的力量，让我们一起将疯狂的想法变成现实！\n\n扫描下方海报中的二维码即可查看 《TiDB in Action》 电子书详情～\n\n![](https://img1.www.pingcap.com/prod/final_poster_19ef1dcb94.jpeg)\n\n>如果您觉得不过瘾，或者还在为没能赶上 TiDB Book Rush 而有些遗憾，可以参与 TiDB User Group (TUG) 推出的 TiDB SOP 、运维手册等系列文档，让零基础新用户快速上手，让老用户轻松线上运维。TUG 非常期待您的加入，每一位 TiDB 用户都会因您的指引而顺利上线～\n>\n>**感兴趣的朋友点击 [这里](http://pingcaptidb.mikecrm.com/bPlTRHh?iro=1) 报名～**","date":"2020-03-09","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"tidb-in-action-finish","file":null,"relatedBlogs":[]},{"id":"Blogs_190","title":"TiDB Contributor 人数突破 400，有关开源理想，我们同在！","tags":["社区","社区动态"],"category":{"name":"社区动态"},"summary":"和一群志同道合的朋友一起做酷且正确的事情，哪怕它是困难的、甚至曾被人认为是不可能的。但，让世界变得更美好，不正是我们踏入开源世界的初衷吗？","body":"从 2015 年 5 月写下第一行代码，TiDB 作为一款新型开源分布式数据库项目，走过了 0 到 1 的**蜕变之日**；走过了存储层 TiKV 项目晋级为 CNCF Incubating Projects 的**光辉时刻**；周边工具逐步完善，**羽翼渐丰**；逐渐走向**成熟稳健**，在近 1000 家用户的生产环境中不断打磨升级。\n\n**这一切荣誉和成就都属于社区——**\n\n**TiDB Repo Contributor 突破 400,**  \n**Thanks for your contributions!**\n\n![](https://img1.www.pingcap.com/prod/1_400_contributor_f9fa537f14.png)\n\n**近一年 TiDB 开源社区架构和治理规则也在不断规范和升级迭代中：**\n\n* 社区自治组织和角色：\n\t* 目前为止，社区启动过 20 个 [Working Group (WG)](https://github.com/pingcap/community/tree/master/working-groups) ， 成立了 5 个 [Special Interest Group（SIG）](https://github.com/pingcap/community/tree/master/special-interest-groups)，它们都有了丰富的阶段性产出；\n\t* 除了已有的 Maintainer、Committer、Contributor 角色之外， 新增了 Reviewer、Active Contributor 角色，让大家找到了“一步步升级打怪”的乐趣。\n\n* 社区活动愈加丰富：\n\t* 除了传统的 [Infra Meetup](https://pingcap.com/meetup/)、[TiDB TechDay](https://pingcap.com/community-cn/techday2019/)、[TiDB DevCon](https://pingcap.com/community-cn/devcon2019/) 线下交流活动，颇具 Geek 精神的 TiDB Hackathon 已成功举办两届，诞生了很多奇思妙想的项目；\n\t* [TiDB 性能挑战赛第一季](https://pingcap.com/blog-cn/pcp-report-202002/) 落幕，[第二季易用性挑战赛](https://pingcap.com/blog-cn/TiDB-usability-challenge-program/) 正在进行中，接下来的 3 个月参赛选手将挑战“让 TiDB 变得更好用”；\n\t* 本周末即将举办 [Book Rush 活动](https://pingcap.com/blog-cn/tidb-book-rush-write-a-book-in-48-hours/)，社区伙伴们挑战 48 小时合写一本 5～6 万字的 TiDB 技术书籍。\n\n* 社区学习版图不断拓宽：\n\t* 面向开源社区开放的 [Talent Plan](https://university.pingcap.com/talent-plan/) 学习计划正在筹备 2.0 升级，整合更多优质学资源，让更多社区伙伴能学、善用，在开源世界、在分布式数据库领域更自在玩耍；\n\t* [PingCAP Education](https://education.pingcap.com/) 上也有面向 DBA 同学的学习资料库，包含线上视频课程还有线下培训，内容干货、形式丰富。\n\n* [TiDB Map](https://github.com/pingcap/tidb-map) 正在完善：\n\t* 为了让每位 TiDB Developer 清晰了解 TiDB 社区的“玩法”，找到自己擅长的方向，我们整理了 [Contribution Map](https://github.com/pingcap/tidb-map/blob/master/maps/contribution-map.md)，展示各个 Repo 中大家可以上手做的事情&参考资料，同时 Map 版图还在不断扩充中；\n\t* 针对 TiDB User Group，我们整理了 [TiDB 集群问题排查地图](https://github.com/pingcap/tidb-map/blob/master/maps/diagnose-map.md)、[性能调优地图](https://github.com/pingcap/tidb-map/blob/master/maps/performance-map.png) ，欢迎大家提出自己的建议。\n\n随着越来越多的人了解和使用 TiDB，我们也愈发认识到要做一款真正解决用户痛点的、属于未来的数据库产品，“道阻且长”，但初心不变：\n\n和一群志同道合的朋友一起做酷且正确的事情，哪怕它是困难的、甚至曾被人认为是不可能的。但，让世界变得更美好，不正是我们踏入开源世界的初衷吗？\n\n*In open source, we feel strongly that to really do something well, you have to get a lot of people involved.（Linus Torvalds）*\n\n**期待未来与更多 TiDB 社区伙伴并肩同行！**\n\n**再次感谢以下 400 位 TiDB Repo Contributor 及所有社区伙伴们的贡献：**\n\n![](https://img1.www.pingcap.com/prod/2_poster_229e1c0a0f.jpeg)\n\n**我们下一个里程碑见！**","date":"2020-03-04","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"number-of-TiDB-contributors-exceeded-400","file":null,"relatedBlogs":[]},{"id":"Blogs_257","title":"一个疯狂的念头：48 小时写一本书，来一次 TiDB 开源社区的行为艺术","tags":["社区","社区动态"],"category":{"name":"社区动态"},"summary":"既然都是做分布式系统的，为什么不尝试下「分布式写书」？TiDB 的社区里有那么多身怀绝技的朋友，社区里也积赞了无数的内容，我们只是需要一个契机将这些内容串联起来。","body":"最近大家可能发现了，TiDB 4.0 发布在即，在 Master 分支上可以看到社区也是一片热火朝天的景象。于是我也在想，对于这个有里程碑意义的 TiDB 版本，我们还能做点什么呢？\n\n其实我一直以来就有个遗憾，这两年 TiDB 的社区日益壮大，也已经有无数的用户也已经将 TiDB 使用了起来，但是市面上一直没有一本关于 TiDB 的技术书籍。这背后其实也有很多原因，例如产品的迭代速度比较快，另外很多时候通过在线文档和社区答疑，问题也就解决了。所以，虽然牵头写书这件事情一直在我的 TODO List 里面，也经常有出版社的朋友和我来约稿，但是总被更加紧急的事情抢占。\n\n**不过，我前几天有了一个「疯狂」的念头，想要约一波 TiDB 社区伙伴，48 小时之内写完这本关于 TiDB 的技术书籍。**\n\n**就在本周末，欢迎大家报名参加！**\n\n## Why？\n\nTiDB 经过这几年的发展，也积累下来了大量的 Blog，文档以及无数的用户积累的最佳实践，但是文档和博客总是有些过于碎片，对于一个社区的想学习和使用 TiDB 的新人来说，如果能有一本入门书籍，系统且简要地介绍一下整个 TiDB 和周边工具生态，另外能手把手地指导用户“把 TiDB 用起来且用好”，那就太好了。很多时候，作为应用开发者和 DBA 也并不希望在使用 TiDB 之前先去读一堆零散的文档和源码阅读文章。\n\n这就是写这本书的初衷。\n\n## Why Now？\n\n前面提到了，TiDB 的演进速度非常快，在过去我们和社区的中心都放在提升核心的成熟度和稳定性上，尤其在 3.0 后，稳定性、性能上都到达了一个比较高的水平，也是在这个版本之后，社区开始加速扩张。\n在 3.0 获得小小的成功后，我们在 4.0 的开发规划中，在持续提升稳定性和性能的同时，将整个产品的易用性、可观测性以及交互体验的连贯性放到了很重要的位置（例如 [KeyViz](https://pingcap.com/blog-cn/observability-of-distributed-system/) ）。**所以，我们觉得 4.0 会是一个更加「好用」的版本，也是一个更适合「写书」的版本。**\n\n## How? \n\n虽然有写书的想法很久了，但是过去我的思路还比较局限，总想着自己写，最近想想，既然都是做分布式系统的，为什么不尝试下「**分布式写书**」？TiDB 的社区里有那么多身怀绝技的朋友，社区里也积赞了无数的内容，我们只是需要一个契机将这些内容串联起来。众人拾柴火焰高，而且很多事情是一鼓作气，就能完成看似不可能完成的事情。\n\n### Book Rush !\n\n#### 活动时间\n\n本周五 21:00 - 周日 21:00\n\n#### 活动内容\n\n参与者在 48 小时内共同完成 [《TiDB in Action》开源电子书](https://github.com/pingcap-incubator/tidb-in-action) 创作，预计全篇长度约 5-6 万字。\n\n内容全部基于 TiDB 4.0 版本创作，但不预设本书的读者有 4.0 之前版本的使用经验，手把手教大家用好 4.0。具体内容包括但不限于：\n\n* TiDB 基本架构原理；\n* 最佳实践及案例：部署、运维（慢查询、热点问题调优）、备份恢复、数据同步和迁移；\n* TiDB 开源社区及周边生态发展历程，及如何参与和贡献。\n\n#### 参与者要求\n\n熟悉 TiDB 的架构原理，有一定的实践经验。\n\n#### 参与者收益\n\n* 如果参与者的贡献内容被审阅通过（PR 被 Merge），名字将会出现在作者栏；\n* 所有作出贡献的参与者将获得活动定制纪念 T 恤一件；\n* 如后续出版了实体书籍，所有参与者将获赠实体书一本（附有 TiDB PMC 成员签名）。\n\n#### 报名方式\n\n请点击 [报名地址](http://tidbcommunity.mikecrm.com/1PMISfw) ，完成表单填写即可报名。\n\n>就像一句俗语说的，  \n>种一棵树最好的时机是十年前，其次是现在。  \n>各位周五晚上见！  \n\n## One More Thing\n\n**疯狂到底**——写书期间，参与者会在 Zoom 会议室中随时沟通写作进展。这个过程将**在 B 站公开直播！**\n\n直播间还会随机掉落 **4.0 新 Features 的开发者连线**介绍架构原理和 Demo Show。\n\n**欢迎围观我们一边写书、一边吐槽（或许有翻车）的全过程。**\n\n直播时间：周六早上 9:00 至周日 21:00，\n\n大家可以提前关注我们的 **B 站账号 [TiDB_Robot](https://space.bilibili.com/86485707)** ！","date":"2020-03-03","author":"黄东旭","fillInMethod":"writeDirectly","customUrl":"tidb-book-rush-write-a-book-in-48-hours","file":null,"relatedBlogs":[]},{"id":"Blogs_161","title":"TiDB 易用性挑战赛开启：解决用户的痛点，让 TiDB 更易用！","tags":["社区","社区动态","TiDB 易用性挑战赛"],"category":{"name":"社区动态"},"summary":"TiDB 挑战赛第二季今天正式开启，赛程持续 3 个月，本赛季将围绕“提升 TiDB 的易用性”展开。考虑到用户们对 TiDB 落地实操中的“易用性”有深刻的体验，我们特地征求了一波 TiDB User Group（TUG）的意见。","body":"**两周前，我们发布了 [TiDB 挑战赛第一季](https://pingcap.com/blog-cn/pcp-report-202002/) 结赛公告，选手们在过去 3 个月里一顿炫酷的操作，让 TiDB 的「性能」产生了“惊人”的提升，比如：**\n\n- .* team 在比赛第一个月就将 IN() 函数性能提升了 150+ 倍，并让 LIKE() 函数性能得到指数级提升；\n- tabokie 让 Titan GC 机制不再受在线写的影响，极大提升了 TiKV 写入性能；\n- pingyu 把 Window 算子和 Sort 算子结合起来，一起进行哈希分组，超预期地提升了窗口函数的性能；\n- …… \n\n**不过比赛结束后，大家好像都有点意犹未尽：**\n\n>参赛选手 A：折腾 TiDB 真有意思，有意思（摇扇子.gif）\n>\n>参赛选手 B：对啊，这得让更多人玩儿起来啊！\n>\n>吃瓜群众 1：那得让 TiDB 更好上手、更好用，玩的人才会多。\n>\n>吃瓜群众 2：不如再来一轮挑战吧，改造一下 TiDB 易用性，让大家能快速上手把玩，感受一下这个炫酷的产品（悄悄地说，我上一季没找到地方下手，求以后多开放些 Repo 选项！\n>\n>参赛选手 C：“易用性”的话，TiDB 用户比较有感受吧，可以问问他们的痛点。\n>\n>TiDB Robot：附议。\n\n## TiDB 挑战赛第二季，说来就来！\n\nTiDB 挑战赛第二季今天正式开启，赛程持续 3 个月，本赛季将围绕“提升 TiDB 的易用性”展开。考虑到用户们对 TiDB 落地实操中的“易用性”有深刻的体验，我们特地征求了一波 TiDB User Group（TUG）的意见。最后根据 TUG 投票的前 20 个需求，再加上我们自己对“易用性”改进的想法，综合设置了本次挑战赛的任务。**值得注意的是：完成用户投票前三的需求会有额外加分哦**！排名前三的需求整体上各自分别加 10000、8000、6000 分。在需求被完整实现或者本赛季结束，该需求对应的加分将由该需求的子任务完成者们一起分享。\n\n本赛季任务依然分三个等级：Easy / Medium / Hard，每个任务对应一定的积分。这次我们优化了本赛季的分级赛制：**如果你是第一次参与挑战赛的新人，Easy 的任务可以直接上手；而老玩家（在该 Repo 历史积分大于 200 分）则可直接挑战 Medium 及以上难度的任务！**\n\n本赛季将有更多 TiDB 相关 Repo 发布任务，大家可以根据自己擅长的方向自由选择：\n\n- [TiDB](https://github.com/pingcap/tidb/projects/26)\n- [TiKV](https://github.com/tikv/tikv/projects/20)\n- [PD](https://github.com/pingcap/pd/projects/2)\n- [Chaos-Mesh](https://github.com/pingcap/chaos-mesh/projects/14)\n- [Data Migration](https://github.com/pingcap/dm/projects/1)\n- [Backup&Restore](https://github.com/pingcap/br/projects/1)\n- [client-rust](https://github.com/tikv/client-rust/projects/3)\n- [tidb-dashboard](https://github.com/pingcap-incubator/tidb-dashboard/projects/17)\n- 持续更新中\n\n比赛结束后，选手可以用积分兑换丰富的奖品，这次兑换奖项也有了大升级！除了 TiDB 限量周边（T 恤、帽衫、双肩包、办公室五件套、黑白游戏机充电宝、书签日历套装），还新增了 **jetbrain toolbox 中任意一个软件的一年 license、PingCAP 年度大会荣誉席**，甚至还有**包机酒的硅谷之行**！此外，完成任意一个任务的选手还可以得到“**完赛纪念徽章**”一枚，长这样👇\n\n![](https://img1.www.pingcap.com/prod/1_usability_challenge_program_d3a5a92f3e.jpeg)\n\n欢迎大家加入 [TiDB Community Slack Workspace](https://join.slack.com/t/tidbcommunity/shared_invite/enQtNzc0MzI4ODExMDc4LWYwYmIzMjZkYzJiNDUxMmZlN2FiMGJkZjAyMzQ5NGU0NGY0NzI3NTYwMjAyNGQ1N2I2ZjAxNzc1OGUwYWM0NzE)，参赛过程中遇到任何问题都可以直接通过 [#tidb-challenge-program channel](https://tidbcommunity.slack.com/join/shared_invite/enQtNzc0MzI4ODExMDc4LWYwYmIzMjZkYzJiNDUxMmZlN2FiMGJkZjAyMzQ5NGU0NGY0NzI3NTYwMjAyNGQ1N2I2ZjAxNzc1OGUwYWM0NzE) 与我们取得联系。\n\n## 报名流程\n\n### 报名方式\n\n发起 Issue 至 [pingcap/tidb-challenge-program/register](https://github.com/tidb-challenge-program/register) repo。\n\n格式要求：\n\n- 标题：UCP/Sign Up\n- 内容：  \n\t如果是个人参赛，请对你自己进行简要介绍，并留下可以与你取得联系的邮箱地址。  \n\t如果是团队参赛，请对你的团队进行简要介绍，写明团队名称，每个团队成员的 GitHub ID，并留下可以与你们取得联系的邮箱地址。可参考示例。\n\n### 注意事项\n\n- 如果以团队形式参赛，每队成员最多三人。\n- 有 PingCAP 内部员工参与的队伍，将作为打星队伍，不参与积分总排名，但所获积分仍具有兑换权益。\n- 如需更改报名信息，需关闭错误报名 Issue，重新开启一个新的 Issue 进行报名，暂不支持在原始 Issue 上进行编辑。\n\n## 赛前准备\n\n- 参考 [Join GitHub](https://github.com/join) 完成 GitHub 账号的创建。\n- 参考 [Installing Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) 在本地环境中安装 Git。\n- 通过 [Set up Git](https://help.github.com/en/github/getting-started-with-github/set-up-git) 配置 Git 访问 GitHub。\n- 阅读“ [挑战赛细则](https://github.com/pingcap/community/blob/master/challenge-programs/challenge-program-season-2-cn.md) ”文档。本次参赛流程较第一季更加科学、细化，比如：挑战某个 medium 以上的题目需要在该题所属 repo 完成 200 分以上的 easy。所以大家比赛前一定要仔细阅读哦～\n\n## 学习资料\n\n我们准备了一些学习资料，方便大家快速上手。\n\n- [TiDB 精选技术讲解文章](https://github.com/pingcap/presentations/blob/master/hackathon-2019/reference-document-of-hackathon-2019.md)：帮助大家轻松掌握 TiDB 各核心组件的原理及功能\n- [数据库小课堂](https://github.com/pingcap/awesome-database-learning)：帮助大家快速熟悉数据库知识，大家可以根据任务所需，有针对性地补充学习\n\n## FAQ\n\n**Q1：如何进行报名信息变更？报名信息变更后积分将如何变化？**\n\n变更报名信息需关闭错误报名 Issue，重新开启一个新的 Issue 进行报名，暂不支持在原始 Issue 上进行编辑。报名信息变更后积分方面的变化有以下三种情况：\n\n- 团队成员增加或减少不会影响团队总积分；\n- 加入团队的新成员个人积分将冻结至加入团队前的状态，加入团队后所获积分为团队所有；\n- 从团队中脱离出来以个人身份参赛的选手不继承团队积分，初始积分为 0。\n\n**Q2：如何放弃/变更已领取的 Issue？**\n\n- 放弃 Issue：在已领取的 Issue 下回复 “give-up-challenge”\n- 变更 Issue：先对已领取的 Issue 执行 “放弃 Issue” 操作，再选择新的 Issue\n\n**Q3：能否邀请 PingCAP 内部员工组队参赛？**\n\n当然可以！我们非常欢迎社区小伙伴与 PingCAP 内部员工共同参赛。PingCAP 小伙伴可以在非工作时间与社区小伙伴一起攻克难题。为了尽可能保证赛事的公平，当 PingCAP 内部员工数在团队总人数中所占比例大于 ⅔ 时，该团队只能选择 Hard 级别以上的 Issue 进行挑战，且团队将作为打星队伍，不参与积分最终排名，但仍保留积分兑换权限。\n\n**Q4：我不记得哪个 Repo 是否完成了 200 分怎么办？**\n\n每个参赛主体在报名之后都会收到 sre-bot 发送的自动回复，回复中包含了当前每个 Repo 的积分。\n\n![](https://img1.www.pingcap.com/prod/2_Ti_DB_Community_31a012aeb9.jpg)\n\n> 进入 [活动官网](https://pingcap.com/community-cn/tidb-usability-challenge/) 查看比赛详情\n> \n>期待与各位一起创造无限可能！","date":"2020-03-02","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"TiDB-usability-challenge-program","file":null,"relatedBlogs":[]},{"id":"Blogs_117","title":"积聚 TiDB 社区力量，让 Talent Plan 来一次升级吧！","tags":["社区动态"],"category":{"name":"社区动态"},"summary":"欢迎大家来“试玩”并提供建议、贡献自己的智慧，一起来打造这门课程，帮助更多社区伙伴们学习、成长！","body":"了解 TiDB 社区的朋友应该都知道 [PingCAP Talent Plan](https://university.pingcap.com/talent-plan/) 这门课程，它的初衷是希望造一个“梯子”，帮助小伙伴们一步步从 Go/Rust 语言、分布式系统基础，到实操练习，最终踏上分布式数据库“高阶玩家”的平台。\n\n目前 PingCAP Talent Plan 诞生 1 年多了，我们想把“梯子”替换成更稳定的“台阶”（未来搞成“自动扶梯”也不一定 ;D），给课程装备来点升级。\n\n**现在我们有了一些课程设计雏形，欢迎大家来“试玩”并提供建议、贡献自己的智慧，一起来打造这门课程！希望 Talent Plan 2.0 课程最终成为 TiDB 社区“共建共享”的智慧结晶，帮助更多社区伙伴们学习、成长。**\n\n## 升级版课程规划\n\n下面是我们构思的 PingCAP Talent Plan  2.0 版本的课程结构：\n\n![课程结构](https://img1.www.pingcap.com/prod/1_fa7e66f2fa.png)\n\nTalent Plan Courses 2.0 Framework如上图所示，我们将 Talent Plan 1.0 的优质资源进行整合，同时增加了一些全新的课程系列，形成了一个**更大的 Talent Plan 学习版图**。Talent Plan 2.0 将涵盖 4 个课程系列，包括：\n\n* **Open Source Collaboration**：面向零基础开源爱好者的开源协作课程，这是一个全新的模块，下文将详细介绍。\n\n* **Programming Language**：面向各种编程语言爱好者，目前已有的是 Go、Rust 语言课程，后续准备新增其他语言。\n\n* **Infrastructure Systems**：面向爱折腾基础架构系统的同学。\n\n* **Deep Dive**：TiDB 生态项目深度解读课程，课程难度由浅入深、层层递进。在已有的 TiDB/TiKV 课程基础上，计划新增 Cloud TiDB 等其他生态项目的课程。\n\n每个课程系列都将新增更多内容，比如 Infrastructure Systems 课程系列，除了大家喜欢的 Distributed System in Rust 课程之外，还将新增用 Go 语言设计的分布式关系型数据库（TinySQL）课程和分布式 Key-Value 数据库（TinyKV）课程，下面将详细介绍。\n\n## Talent Plan 2.0 新亮点\n\n### 1. 面向开源爱好者的开源协作系列课程\n\n这是我们专门为**零基础开源爱好者**准备的全新课程，希望即使是技术小白也能进入开源世界玩耍，比如不同开源软件许可协议的差异、知名开源基金会（Linux、Apache、CNCF 等）的运作方式以及开源社区运营的基础知识，快速掌握参与开源项目的小技巧。目前这个课程系列的学习资料已经准备完毕，3 月 2 日将开启为期 10 天的开源协作系列课程体验计划，任何对开源感兴趣的小伙伴都可以加入 [Talent Plan Courses Working Group](https://tidbcommunity.slack.com/archives/CR746G049) 参与课程体验，体验过程中你可以：\n\n* 分享学习成果和感受；\n\n* 补充其他开源相关的有价值的学习资料；\n\n* 为课程作业的设计贡献 Idea。\n\n无论是以上哪种方式，你都能为这个课程系列贡献自己的一份力量。\n\n## 2. 用 Go 语言设计的分布式关系型数据库（TinySQL）课程\n\n[TinySQL](https://github.com/pingcap-incubator/tinysql) 课程是基于 Go 语言实现的分布式关系型数据库，相比于 Talent Plan 1.0，会更加全面，几乎涵盖了分布式数据库 SQL 层最重要的部分。该课程会按照一个由简单到复杂，由静态到动态的顺序展开：\n\n* 首先我们将对 SQL 和关系代数有一个简单的了解，为后面的课程做准备；\n\n* 接下来，我们将聚焦一个只读 SQL 的执行，从 Parser 如何解析语义，到执行器如何执行语义，并在最后去了解优化器如何选出最优的执行计划；\n\n* 最后，我们将聚焦在那些改变数据状态的 SQL（包括 DML 以及 DDL），以及如何处理它们和只读语句之间的相互影响。\n\n目前课程的代码框架已经完成实现，课程材料也正在准备中，欢迎社区小伙伴参与早期测试或者课程材料的编写。\n\n### 3. 用 Go 语言设计的分布式 Key-Value 数据库（TinyKV）课程\n\n\n[TinyKV](https://github.com/pingcap-incubator/tinykv) 课程是基于 Go 语言全新设计的分布式 Key-Value 数据库课程。类似已有的 Distributed System in Rust 课程，TinyKV 同样受著名的 MIT 6.824 所启发，但更加接近 TiKV 的实现。我们引入调度相关逻辑，学员可以从 0 到 1 实现一个完整可用的分布式 KV 服务。课程主要分为四个部分：\n\n* LAB1：实现单机 KV server；\n\n* LAB2：基于 Raft 实现多副本高可用 KV server；\n\n* LAB3：实现 Multi-Raft 以及数据均衡调度；\n\n* LAB4：基于 Percolator 模型实现分布式事务。\n\n当完成课程后，大家将会从实践中对 Raft 协议、Percolator 分布式事务模型有更深刻的理解。同时大家在实现 TinyKV 的过程中，也会更加了解 TiDB + TiKV + PD 的实际框架了，之后深入研究 TiDB/TiKV/PD 的源码会更加游刃有余。目前，我们已经完整实现了一个可用的 TinyKV 和相关测试，接下来会通过不断修剪得到课程需要的框架代码，同时课程材料也在紧锣密鼓地进行编写中。欢迎社区小伙伴参与早期测试反馈建议以及文档的查漏补缺。\n\n### 4. 作业分发、提交、分数评估及反馈更加自动化\n\n为了给小伙伴们更好的参与体验，并提高作业分发效率，我们调研了国内外大学在教学过程中使用的优秀工具，目前在重点针对 Github Classroom 进行作业分发功能的测试。除此之外，作业评估工作也将采用在工业界被广泛采用的 CI 技术，作业结果反馈会更加快速、高效、自动化。\n\n## 试玩及反馈通道\n\n以上课程及自动化作业分发工具都还处于调试阶段，大家可以加入 [Talent Plan Courses Working Group](https://tidbcommunity.slack.com/archives/CR746G049) 参与 2.0 课程体验、交流或吐槽，期待与各位共同打磨这门课程！\n\n另外，在 2.0 课程细节完全敲定对外公布之前，大家依然可以继续学习 Talent Plan 1.0，作业提交与成绩评定规则与之前保持一致，更多细则详见 [PingCAP Education 官网](https://education.pingcap.com)。","date":"2020-02-28","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"talent-plan-readies-to-level-up","file":null,"relatedBlogs":[]},{"id":"Blogs_249","title":"原来提升一个数据库的性能并没有那么难！TiDB 性能挑战赛完结撒花","tags":["TiDB 性能挑战赛","社区动态","社区"],"category":{"name":"社区动态"},"summary":"性能挑战赛已经圆满落幕，最终的积分排行也新鲜出炉，选手们的参赛成果让人非常惊喜，让我们回顾一下选手们是如何在“TiDB 性能提升”之路上，过五关斩六将的吧～","body":"2019 年 11 月初，我们开启了「TiDB 挑战赛第一季之 [性能挑战赛](https://pingcap.com/community-cn/tidb-performance-challenge/)」，比赛为期三个月，期间选手将通过完成一系列难度不同的任务来获得相应的积分。赛程过去三分之一时，已经取得了十分耀眼的 [阶段性成果](https://pingcap.com/blog-cn/pcp-report-201911/)。三个月过去，性能挑战赛已经圆满落幕，最终的积分排行也新鲜出炉，选手们的参赛成果让人非常惊喜，让我们回顾一下选手们是如何在“TiDB 性能提升”之路上，过五关斩六将的吧～\n\n## 最终积分排名与奖项揭晓\n\n![积分排行榜](https://img1.www.pingcap.com/prod/1_Integral_ranking_734e3fc90f.png) \n\n>注：本次比赛的完整积分榜详见 [活动页面](https://pingcap.com/community-cn/tidb-performance-challenge/) 。\n\n本次 TiDB 性能挑战赛，总共有 165 位社区开发者参赛，包括 23 支参赛队伍和 122 位个人参赛者（按照比赛规则，有 PingCAP 人员参与的小组不计入挑战赛最终排名，即上图中有 TiDB Logo 标示的选手）。\n\n本次比赛奖项设置为：一等奖 1 名，二等奖 2 名，三等奖 3 名，其余分数高于 600 分的团队或个人为优秀奖，各团队和个人的获奖情况如下：\n\n*   一等奖：.* Team（15050 积分）。\n\n*   二等奖：niedhui（4300 积分）和 catror（3500 积分）。\n\n*   三等奖：pingyu（2600 积分）、Renkai（2550 积分）和 js00070（1800 积分）。\n\n*   优秀奖：ekalinin（1450 积分）、mmyj（1050 积分）、AerysNan（750 积分）、MaiCw4J（650 积分）、Rustin-Liu（650 积分）和 koushiro（650 积分）。\n\n感谢这些非常优秀的团队和个人参赛者，在他们的贡献下，TiDB 各方面的性能都有了飞跃式的提升（后文会为大家展示其中几个优秀项目的提升效果）。此外，非常感谢 PingCAP 内部的参赛同学，他们利用自己的业余时间参赛，为 TiDB 的性能提升做出了突出的贡献，他们将获得我们颁发的突出贡献奖：\n\n*   tabokie：通过“[PCP-21: Titan GC doesn’t affect online write](https://github.com/tikv/tikv/issues/5739)”直接获得 27000 积分，一举登顶积分榜首。\n\n*   july2993：通过完成多项 PCP 任务获得高达 3000 的积分，位于总积分榜第 5 名。\n\n## 选手感想\n\n“作为内部人员参加这次大赛，最大的体验就是周末工作还是蛮累的;)，但和日常工作不同的是，PCP 的难题更具探索性和未知性。作为参与者担当了一次业界前沿工业实践的先头兵，忘掉 OKR 轻装上马，重新找回了初恋代码的滋味。最后，尽管贵司从来不缺夸奖，我还是得夸一夸这赏心悦目的代码库，功能扩展不费吹灰之力，当然还要感谢 mentor 兼同事们对选题的前期探索，在宝贵周末共同探讨难题，我的工作只是从纸面迈出的一小步，优秀的团队给了我最大的鼓励。”\n\n——tabokie\n\n\t\n“我们参加了去年的 hackathon 比赛并斩获了二等奖。这次性能挑战赛在队长的带领下也取得了总积分榜第二的好成绩。导师很认真负责，交流起来完全没有架子。前期的分数有时候有 bug 但反馈之后很快修复，希望下一届规则可以更完善一些，学到了很多东西（比如 Rust），下一届会继续参赛！”\n\n—— .* team\n\n“参与性能挑战赛收获很大，有厉害的导师针对选定问题进行指导，把以前很多零碎的知识汇成了完成的知识体系，最终能看到自己的代码对 TiDB / TiKV 的性能提升是一件非常有成就感事（TiDB Robot 插播：niedhui 已经是 TiKV Committer 了！）”\n\n—— niedhui\n\n\n“TiDB 的知乎和公众号我一直在关注，看到这个活动觉得还挺有意思的，做开源贡献的同时竟然还有奖品。另外因为去年下半年学习了 Go 语言就借此机会多练习一下。比赛体验很好，稍微难一点的题目都有导师指导，而且 code review 也做的很细心，这对刚开始接触 TiDB 代码的人十分友好。要说获得了什么，那就是还在你们手里没有给我寄的奖品哈哈（TiDB Robot：等我们回公司了就给你寄～）”\n\n——Catror\n\n## 优秀成果展示\n\n在比赛开始一个月的时候我们曾经做过一次 [成果展示](https://pingcap.com/blog-cn/pcp-report-201911/)，已经过去了两个月，让我们再来回顾一下两个月中参赛选手们取得的优秀成果吧！\n\n### PCP-21: Titan GC doesn’t affect online write\n\n*   [相关 PR 链接](https://github.com/tikv/tikv/issues/5739)\n\n*   作者：tabokie\n\n这是整个赛季中唯一一个被完成的 Hard 等级的任务，tabokie 凭借该任务直接获得 27000 分，在比赛的最后一天逆袭绝杀，登顶性能挑战赛榜首！\n\n#### 题目简介\n\nTitan 是 TiKV 开发的一款实现键值分离的 RocksDB 插件，简单来说，就是将较长的用户键值对单独存储在 Blob 文件中，而将数据在 Blob 文件中的物理地址写在 RocksDB 中。当用户删除 RocksDB 中的数据时，物理地址对应的数据随之失效，Titan 通过对 Blob 文件的定时垃圾回收来清理这些无效的数据。GC 的过程就产生了本题目所描述的问题：数据清理后多个 Blob 文件的重新整合产生了新的物理地址，我们需要把它们一一写回 RocksDB 中，而 Titan 当前的 GC 机制要求写回 RocksDB 的同时阻塞用户对 RocksDB 的写入操作。\n\n具体来说，GC 写回时执行了读操作，当且仅当需要写回的数据较新时才会确认写回，整个过程中 RocksDB 不能有新数据插入。这一机制严重影响了数据库的写入性能，尤其对于更新频繁进而导致 GC 频繁的场景，写入性能将急剧下降。\n\n#### 实现方法\n\ntabokie 采用了一种稍微妥协的方式，利用 RocksDB 提供的 Merge Operator 特性，优化 GC 性能。开启 Merge Operator 后，除了正常数据，还可以插入 Merge 类型的数据，RocksDB 会自行将正常数据与其后的 Merge 数据按照插入时序进行合并，这样的合并发生在 Read/Flush/Compaction 过程中，在读写性能之间找到了一个可以接受的平衡。使得后台 GC 不再影响写入，大大提升了 Titan 的写入性能。\n\n#### 效果展示\n\n我们使用 YCSB（一款专门针对 NoSQL 数据库的基础测试工具）测试开启了 Titan 的 TiKV 数据库，本例中使用了纯 update 配置，后台 GC 线程为 6，测试结果如下：\n\n![YCSB](https://img1.www.pingcap.com/prod/2_YCSB_f1c6d6896a.png) \n\n在持续 8 分钟的测试中，因为测试前期 GC 频率较轻，优化前后两种 GC 机制的写入性能差距很小。随着写入时间的增加，到后期，两种 GC 机制下的写入性能差距迅速扩大，二者的 QPS 差距可达到 3000！可以期待的是，在长时的生产环境中这样的优势能够持续保持，将显著地提升用户的写入体验！\n\n### PCP-6: Optimize the performance of builtin function `IN` \n\n*   [相关 PR 链接](https://github.com/pingcap/tidb/issues/12970)\n\n*   作者：js00070（张之逸）\n\n#### 题目简介\n\n内置函数 `IN()` 被用来处理 SQL 中的 in 操作，如 select id, age from students where age in (18, 19, 20)，是一个比较常见的函数。有时应用拼接的 SQL 中 `IN()` 表达式的参数个数能够达到上万个，且基本上都是常量，如上面的例子。在此种情况下，每收到一行待处理的数据，TiDB 都会去这些常量做一次重复的求值计算，非常低效。\n\n#### 实现方法\n\n该任务由 js00070（张之逸）完成，主要思路是在内部构造 `IN()` 表达式时，区分出常量和非常量参数，用一个 HashMap 保存常量的值，避免运行时的重复计算。对于上面例子中的 SQL，18、19 和 20 这三个常量就会被保存在 HashMap 中。经过这个优化后，对于常量参数，其计算复杂度从原来的 O(n) 降低到了 O(1)。大大提升了这种情况下 `IN()` 表达式的运行效率。\n\n#### 效果展示\n\n优化的效果主要取决于参数内的常量个数，我们以 IN 包含 2 个常量参数，1 个非常量参数作为输入，对各类型数据处理 1024 行的 benchmark 结果如下图：\n\n![](https://img1.www.pingcap.com/prod/3_Effect_display_benchmark_548ca29a57.png) \n\n### PCP-4: Improve the performance of `WindowExec` by using multi-thread hash grouping\n\n*   [相关 PR 链接](https://github.com/pingcap/tidb/issues/12966)\n\n*   作者：pingyu \n\n#### 题目简介\n\nTiDB 的 Window 算子原来实现是单线程的，对于 Window 算子的每个窗口，因为是数据隔离的，所以每个窗口之间可以通过并行计算来提升计算效率。\n\n#### 实现方法\n\n算法的原理很简单，按照窗口函数的 partition by 从句指定的列来进行哈希分组，再对于每个分组，单独起一个线程做计算。pingyu 经过多次实验、测试和改进，把 Window 算子和 Sort 算子结合起来，一起进行哈希分组，在每个线程内先将数据排序，再做窗口函数计算。最终得到了非常好的性能提升，超出预期的完成了此 PCP 题目。\n\n附上 pingyu 本人对这项工作的分享：[Optimize the Performance of Window Executor](https://docs.qq.com/slide/DRG5qZkdmRW9CZ2NM)。\n\n目前 pingyu 正在研究周靖人的 Paper 《[Incorporating Partitioning and Parallel Plans into the SCOPE Optimizer](http://www.cs.albany.edu/~jhh/courses/readings/zhou10.pdf)》，尝试将 partitioning 属性集成到 TiDB 的优化器当中去，使优化器可以根据代价来选择是否插入 shuffle 算子，这一优化有望改变 TiDB 执行引擎的并发模型，使其充分利用计算机的 CPU 资源，提升执行引擎性能，非常值得期待！\n\n#### 效果展示\n\n如下图，横轴代表并发数量，纵轴代表一个有窗口函数的 SQL 的 QPS，并发数量为 1 时和原来单线程的执行性能一样。可以看到，在并发数为 4 时，Window 算子的计算效率达到了单并发执行的 2.2 倍：\n\n![](https://img1.www.pingcap.com/prod/4_Effect_display_SQL_QPS_876a6b7d84.png) \n\n### PCP-2: Improve the performance of `groupChecker` by vectorization\n\n*   [相关 PR 链接](https://github.com/pingcap/tidb/issues/12976)\n\n*   作者：Reminiscent（鄢程鹏）\n\n该任务由杭州电子科大的鄢程鹏同学完成，他去年参加了 Talent Plan 并顺利结业，除了参加性能挑战赛以外，也正在积极参加 Cascades Planner 的优化器重构工作，为优化器添加了很多优化规则。\n\n#### 题目简介\n\n`groupChecker` 在 TiDB 中被用来分组，会被 Stream Aggregate，Merge Join，Window 这三个算子使用。为保证正确性，它要求输入数据是有序的，通过两两比较的方式判断前后两行数据是否属于同一个数据分组。\n\n在分组过程中，有可能按照某个表达式来进行分组，如 `GROUP BY col1 + col2`，`groupChecker` 会逐行的调用表达式的 `Eval()` 接口进行计算，这个过程的计算开销非常大。\n\n#### 实现方法\n\nTiDB 在计算时，内存中的数据是按列存放的，考虑到 Cache Locality，按列计算性能会更快。针对这个特点，程鹏做了两个优化：\n\n1.  使用表达式最新的列式计算接口，一次性求解一列的值，降低 Cache Miss。\n\n2.  分组时也借用向量化的思想，按列进行比较，进一步降低 Cache Miss。\n\n#### 效果展示\n\n后续程鹏帮助我们把优化后的 `vecGroupChecker` 用在了 Window 和 Stream Aggregate 算子内，另一位同学 Catror 把它用在了 Merge Join 算子内，都对这三个算子产生了很大的性能提升。\n\n效果如下图所示，Window 算子优化前后的执行时间对比，越低性能越好：\n\n![](https://img1.www.pingcap.com/prod/5_Effect_display_time_95793a8c63.png) \n\n### PCP-24: Improve the performance of the HTTP API for getting all regions\n\n*   [相关 PR 链接](https://github.com/pingcap/pd/issues/1837)\n\n*   作者：ekalinin\n\n该任务由俄罗斯小哥 ekalinin 完成，这位小哥曾凭借一己之力拿到 PCP 单日榜首，目前已完成 20+ 向量化表达式的工作。\n\n#### 题目简介\n\n在生产环境中，有时需要通过获取所有的 region 信息来帮忙分析集群的状态。在实验环境中，有时也需要通过收集 region 的信息对集群访问模式进行一些分析。当集群存储的数据越来越多，region 的个数达到百万级别以上后，获取全量的 region 信息所需要的计算和时间开销变得巨大无比。本题目希望优化该 API 的性能，减少资源使用，降低对 PD 在线服务的影响。\n\n#### 实现方法\n\n在获取 Region 过程中，主要消耗在于中间的内存拷贝和序列化，因此这两块是优化的大头：\n\n1.  从 []byte 到 string 的转化做到 zero-copy。\n\n2.  优化 Hex Encoding 和大小写转换中的内存消耗，减少内存的申请。\n\n3.  使用 Streaming 的方式序列化输出。\n\n#### 效果展示\n\n在我们简单测试场景中 100w regions 对比中，API 的整体性能提升了 3.5 倍，尤其是 Hot Path 上的 `RenderJSON()` 函数，其运行时间和内存开销都被大大减小，前后对比的 benchmark 结果如下图所示： \n \n![](https://img1.www.pingcap.com/prod/6_Effect_display_benchmark_e59431bb4f.png) \n\n## 总结与展望\n\n目前这些优化都会合进 4.0 分支，将随着 TiDB 4.0 版本发布并交付给用户，预计 5 月底 4.0 的用户就能够享受到这些性能优化带来的体验改进了，让我们小小的期待下 4.0 版本的惊艳表现。\n\n**至此 TiDB 挑战赛第一季落幕，错过比赛或没玩够的小伙伴们不用遗憾，第二季挑战赛也即将开启！**\n\n第二季主题的灵感来自去年 AskTUG 上发起的 [“我的 TiDB 听我的”](https://asktug.com/t/topic/2156) 活动，该活动累计收到 TiDB 用户们关于 DDL、分区表、性能优化、TiKV、PD 等方面的近 40 个需求。经过一轮筛选，我们列出了 20 个尚未实现的需求 [向用户征集投票](https://asktug.com/t/topic/2684)，后续我们将结合用户的投票结果及其他 TiDB 易用性相关的问题，开启第二季 TiDB 挑战赛，敬请期待！","date":"2020-02-18","author":"Jian Zhang","fillInMethod":"writeDirectly","customUrl":"pcp-report-202002","file":null,"relatedBlogs":[]},{"id":"Blogs_240","title":"TiExciting —— 让 TiDB 部署轻松简单","tags":["运维"],"category":{"name":"社区动态"},"summary":"本篇文章将介绍在 Hackathon 获得三等奖的 TiExciting 项目，它可以帮助更多人用上 TiDB 并改善运维的复杂度。","body":"运维难，难于上青天。\n\n作为 PingCAP 员工，我们不仅平时自己用着 TiDB，也会自发的想让周围人也用上 TiDB。但在这个过程中，我们发现有以下问题：\n\n*   上船难：官方推荐的部署方法 TiDB Ansible 限制较多，有一定的学习成本。对于运维同学比较容易上手，但是对于研发同学就比较不友好。用户手册详细但是复杂，其中也有各种各样的限制，特别是遇到错误的时候不好处理。\n\n*   开船难：用上 TiDB 之后，后续对 TiDB 集群进行运维（如扩容，升级），尤其在 PD 的扩容和缩容，安全性高，但是操作还是有些复杂。\n\n*   开发上船容易翻：经常见到开发人员不知道水有多深，跟着文档在自己机器上尝试用 TiDB Ansible 部署 TiDB，结果一不小心就把系统改得面目全非。\n\n为了改进和解决这些痛点，我们组队参加了 [TiDB Hackathon 2019](https://mp.weixin.qq.com/s/3-ww6MJnygvq8mpkDuwAig) 比赛，编写了 TiExciting 项目，并最终获得大家的认可拿到了三等奖。\n\n## 当前的上船门槛有多高？\n\n在参赛前，我们先评估了一下之前的体感问题是不是真实存在的问题，因此我们在本次 Hackathon Ucloud 新集群上进行了一番实测：\n\n- 队友 A：腾讯微信研发，从未接触过 TiDB，首次尝试部署：\n\n    - 按照 TiDB Ansible 超长的部署教程，部署 3 小时后没有成功，遂放弃。\n\n- 队友 B：PingCAP 华东地区高级客户支持，为各种商业客户部署过 TiDB：\n\n    - 操作熟练，但经常由于手滑或环境关系经历各种报错，凭丰富的知识知道怎么解决，最终使用 20 分钟部署完毕。\n\n综上，实践表明，不论是新手还是老手，都要经过很复杂的步骤才能开始真正用起 TiDB 产品。另外，TiDB Ansible 本身还对部署环境提出了极高的要求，例如公有云环境直接无法通过入门检测，这些都会劝退大量新用户。\n\n## 怎样可以快速上船和开船？\n\n为了解决问题，我们先进行了需求设计：\n\n- 为了能快速上船，部署过程本身应该要做到「快」，能并行的操作就并行进行。\n\n- 直观方便清晰，最好不要文档就能用起来：提供图形化界面。\n\n- 所有与易用性冲突的特性都需要让步。\n\n    - TiDB Ansible 强制环境检查 → TiExciting 不阻止部署（但给出 Warning）。\n\n    - TiDB Ansible 要求从中控机部署 → TiExciting 甚至可以从 Windows 开始部署，且不要求配置互信。\n\n- 绿色环保有节操，没有全家桶。\n\n    - TiDB Ansible 强制要求进行系统配置调优满足 TiDB 要求 → TiExciting 允许用户可选地配置系统以便更好地运行 TiDB，且用户知悉各个要进行的改动。\n\n    - TiExciting 允许用户自行勾选想要安装的组件，遵循最小化原则。\n\n当前安装都是安装一路绿灯，环境检查只做告警，不推荐在生产环境使用。后期我们会添加严格模式，来做生产集群管理。**时刻对生成环境抱有敬畏之心。**\n\n## Hackathon 成果\n\n### 部署\n\n创建完目标机器（后文介绍机器添加方式）后，就可以**自由选择其中的机器进行部署**。界面上可以**自行勾选想要的组件**，或取消勾选不想要的组件。比如不想要监控大礼包，就可以直接取消勾选「监控」。另外 TiDB 也是可以取消勾选的，适用于只想使用 TiKV 的情况。\n\n![图 1 部署方案](https://img1.www.pingcap.com/prod/1_be544299ea.gif)\n\n<div class=\"caption-center\"> 图 1 部署方案</div>\n\n选择完组件后，**界面会自动根据节点数量、想要的组件生成部署方案**。当然，作为 Hackathon 作品，这里的自动方案不一定是最合理的，以及实际场景中用户很可能想要进一步自行定制拓扑，**因此用户可以在这个界面上拖拽各个组件来重新决定拓扑**，或添加新组件。一般来说，如果只是不严格想体验一下分布式 TiDB 的话，包括只有一个节点等情况，用户直接采用默认的拓扑即可，非常友好。\n\n然后演示下最后安装的效果：\n\n![图 2 安装演示](https://img1.www.pingcap.com/prod/2_556f8af819.gif)\n\n<div class=\"caption-center\"> 图 2 安装演示</div>\n\n### 管理机器\n\n启动 TiExciting 后，界面会引导用户首先增加机器，包括填写连接方式等。这里可以指定密码或密钥登录，无需 root，也无需创建特别的用户，只需填写运维人员平时连接上去的方式即可。增加机器时候的设置也可以从现有机器设置复制。\n\n![图 3 服务器添加演示](https://img1.www.pingcap.com/prod/3_4c43f74c2b.gif)\n\n<div class=\"caption-center\"> 图 3 服务器添加演示</div>\n\n\n高级配置中可以指定位置标签，包括这个机器属于什么机架，及这个机器属于什么机房。如果有指定位置标签，配置完毕后就会在界面上按照机房和机架组织显示这些机器，非常直观。\n\n![图 4 高级配置](https://img1.www.pingcap.com/prod/4_1e03b0591d.gif)\n\n<div class=\"caption-center\"> 图 4 高级配置</div>\n\n完整成果演示视频可以点击这里：[TiExciting Demo 视频](https://drive.google.com/open?id=1v62lqGhOXNxTCMr7RKuKxuAfBCWZT4SF)\n\n## 技术实现\n\n### 界面\n\n为了能跨各个平台展示界面，TiExciting 是以 Web 形式提供界面的，使用了比较流行的 React + MobX 方案实现。这样，不仅 TiExciting 的界面是跨平台的，而且即使 TiExciting 运行在无 UI 的服务器上，也能在用户浏览器上远程访问到界面。\n\n### 跨平台\n\nTiExciting 的部署逻辑及响应用户操作的逻辑是采用 Python 编写的，来达成跨平台的目的。我们设想采用 Python 打包工具来实现用户一键下载打开运行且不需要安装的理念，但实际 Hackathon 上用下来发现它只能是个设想，坑还是挺多的。另外 Python 本身 runtime 就很大。如果再给我们一次机会，大概会改用 Golang 吧，生成一个 binary 是真的很简单。\n\n### 快\n\n为了尽可能地快，TiExciting 会尽可能地基于文件哈希来复用文件，例如已下载且校验通过的 TiDB 二进制大礼包就不需要重复下载，已经成功部署的同理。TiExciting 还实现了异步有向无环图的任务调度机制，当所有先决任务完成后，后续任务就可以得到执行，且之间没有依赖关系的任务可以并行执行，如下图所示：\n\n![图 5 异步有向无环图的任务调度机制](https://img1.www.pingcap.com/prod/5_6aae98abe6.png)\n\n<div class=\"caption-center\"> 图 5 异步有向无环图的任务调度机制</div>\n\n## 聊聊未来\n\n因为 Hackathon 时间有限，其实还有很多没来得及做但想做的功能：\n\n- 更好的部署方案规划。\n\n- 纯界面实现扩容、缩容。\n\n- 纯界面实现更新集群。\n\n- 纯界面管理集群（启动、停止、更新、滚动等）。\n\n- 将现有 TiDB Ansible 集群纳入 TiExciting 管理。\n\n虽然 Hackathon 已告一段落，但我们希望将来能进一步完善 TiExciting，将它想做的都落地下来，成为一个大家喜欢用的通用的工具，帮助更多人用上 TiDB 并改善运维的复杂度。","date":"2020-01-09","author":"王军","fillInMethod":"writeDirectly","customUrl":"tiexciting-makes-tidb-deployment-easy-and-simple","file":null,"relatedBlogs":[]},{"id":"Blogs_146","title":"汇聚能量，元气弹发射 | PingCAP Special Week - Tools matter 有感","tags":["Tools"],"category":{"name":"社区动态"},"summary":"2019 年第四季度，PingCAP Special Week 的主题是 Tools matter，本篇文章将介绍本次 SW 都有哪些不错的成果。","body":"对于 80 后的男生来说，『七龙珠』是一部绕不开的经典漫画，里面的主角孙悟空掌握了一项强大的必杀技 - 元气弹，他通过收集万物的能量，汇聚成一个有巨大破坏力的能量球，然后发射给反派将其打败。每每在漫画里面看到这样的情况，年少的我就激动不已，梦想着有一天也可以自己举起双手，汇聚出元气弹。\n\n当然，现在我们知道举起双手是不可能造出元气弹了，但从另一方面来说，如果我们能很好地利用好大家的力量，统一的往一个方向努力，解决某一个特定的问题，这不就是另一种元气弹的形式吗？在 PingCAP，我们每个季度都会做这样一次活动，叫做 Special Week（后面简称 SW），在 2019 年第四季度，我们 SW 的主题是 - Tools matter，很直白，就是工具很重要。\n\nPingCAP 一直致力于跟社区一起构建 TiDB 的生态，这其中 Tools 扮演了非常重要的角色。大家可能会用 TiDB Data Migration（以下简称  DM）将 MySQL 的数据迁移到 TiDB，或者使用 TiDB Binlog 工具将 TiDB 的数据同步到下游其他的服务。\n\n这次 Special Week 希望集思广益，从其他角度来改进 Tools，降低大家使用 TiDB 的门槛。\n\n为了将 SW 相关的进度公开到社区。我们创建了一个 [GitHub project](https://github.com/orgs/pingcap/projects/6) 来放置所有的开发任务，研发的同学自行组队去挑战相关的任务。经过了 5 天的全力开发，我们取得了一些不错的成绩，下面跟大家一起看看我们有了哪些不错的成果。\n\n## 增量备份\n\n在这次活动中为 TiDB 新推出的 [分布式快速备份和恢复工具](https://pingcap.com/docs-cn/dev/how-to/maintain/backup-and-restore/br/)（简称：BR） 实现了增量备份和恢复功能。效果展示如下：\n\n![1-br-效果图](https://img1.www.pingcap.com/prod/1_0351162b7b.gif)\n\n搞定增量备份和恢复功能，对于完善基于 TiDB Binlog 的灾备集群方案具有重要意义。大家都知道 TiKV 使用 Raft 协议实现数据多副本来保证 TiDB 集群的数据安全，而 TiDB Binlog 某种意义上是 TiDB 集群的另一份冗余数据，如果我们再实现 TiDB Binlog 多副本，复杂且意义不大。但是当 TiDB Binlog 出现数据损坏，对灾备集群等使用场景影响是重大的。增量备份和恢复功能可以快速填补上 TiDB Binlog 数据损坏的时间段数据，大大缓解方案上的这一缺陷，疗效堪称快速续命丸。\n\n## DM 高可用\n\n让 TiDB 自研的 [DM](https://github.com/pingcap/dm)（从 MySQL 迁移数据到 TiDB 的工具） 支持了高可用的特性，使得用户免于遭受在节假日甚至凌晨发现挂掉一台服务器而紧急 OnCALL 的苦恼，也为 DM 可以用在一些关键场景中做了铺垫。\n\n下图是实现 DM 高可用的架构图:\n\n![DM 高可用的架构图](https://img1.www.pingcap.com/prod/2_e10ef20e58.png)\n\n## Tools Chaos 测试\n\nChaos Mesh 是我们最新开发的，基于 Kubernetes（K8s） 的一套 Chaos Engineering 解决方案，只要你的服务能跑在 K8s 上面，就可以直接集成 Chaos Mesh 进行 chaos 测试。\n\n![chaos-mesh](https://img1.www.pingcap.com/prod/3_a06046c5fd.png)\n\n在这次 SW，我们将 DM、TiDB Binlog、BR 以及 CDC 都成功地跑在了 K8s 上面，然后使用 Chaos Mesh 进行了测试，也发现了一些问题，改善了整个 Tools 的稳定性。\n\n我们在 2019 年 12 月 31 日正式开源 Chaos Mesh，项目地址：[https://github.com/pingcap/chaos-mesh](https://github.com/pingcap/chaos-mesh)，欢迎大家使用。\n\n## 生态合作\n\n在本次 SW 我们也欣喜地看到，一些企业也有很强烈的意愿跟我们一起来构建工具的生态，这次 SW 我们主要跟外部企业一起进行了三个项目：\n\n### PITR ( Point in Time Recovery)\n\n这个项目是跟某互联网公司一起进行的，主要是将 Binlog 的增量备份进行合并，生成一个更轻量级的备份文件，加速同步的速度（项目地址 [https://github.com/lvleiice/Better-PITR](https://github.com/lvleiice/Better-PITR) ）。\n\nPITR 的核心功能在之前 PingCAP 举办的 2019 Hackathon 中已经完成，详见《[直击备份恢复的痛点：基于 TiDB Binlog 的快速时间点恢复](https://pingcap.com/blog-cn/fast-pitr-based-on-binlog/)》，在这次 SW 我们将其进一步完善增强，主要包括：\n\n1.  增加 CI，提升测试覆盖率。\n\n2.  修复读取历史 DDL 报错问题。\n\n3.  对压缩前预处理阶段提速，200 条 DDL 测试下，相比之前，提速 68 倍。\n\n后续，我们仍然会继续跟社区一起合作完成该项目，我们也在 Slack 上面建立了相关的 [working group](https://tidbcommunity.slack.com/?redir=%2Farchives%2FCRH5594F8)，欢迎感兴趣的同学参与。\n\n### TiKV Raw 模式备份恢复\n\n除了直接使用 TiDB，有些用户也会直接使用 TiKV，现阶段我们只提供了 TiDB 的备份工具 - BR，并没有单独针对 TiKV。\n\n所以在这次 SW 我们跟一点资讯一起合作，让 BR 支持了 TiKV 的备份和恢复。现在已经完成了 BR 这一段的开发，还剩 TiKV 这边一点工作的收尾，欢迎感兴趣的同学关注 [https://github.com/pingcap/br/issues/86](https://github.com/pingcap/br/issues/86)。\n\n### 基于 DM 支持 Syncer\n\n为了方便用户将 MySQL 的数据同步给 TiDB，我们早期开发了 syncer 这个工具，后来为了支持更强大的功能，我们开发了一套新的同步工具 - DM。DM 易用性，稳定性更强，并支持高可用。后期我们会逐步废弃掉 syncer ，不再同时维护 DM 和 syncer 两套代码。但出于历史原因一些用户仍然在使用 syncer，如何方便地从 syncer 迁移到 DM，是我们这次 SW 要解决的问题。\n\n我们跟某知名互联网金融公司合作，基于 DM 的 sync 模块开发另一个 syncer，兼容之前老的 syncer，让用户能无缝迁移。\n\n现在相关的开发进度在 [https://github.com/pingcap/dm/pull/433](https://github.com/pingcap/dm/pull/433)，欢迎大家参与。\n\n## 写在最后\n\n经过接近一年的探索，Special Week 在 PingCAP 已经逐渐成为一个独特的文化。刚刚结束的 Q4 Sepcial Week 把 PingCAP 与用户和开源社区紧密结合在了一起。我们希望与社区在未来有更多的合作，完成更多有价值的项目。这也是为什么大家可以看到这次的 SW 的大部分讨论，设计，进度都公开到 GitHub 的原因。\n\n我们会整合这次 Sepcial Week 中产生的项目，建立一些社区可以参与的工作组，欢迎大家从 [这里](https://github.com/pingcap/community/tree/master/working-groups) 找到自己感兴趣的工作组，与我们一起构建 TiDB 生态工具社区。","date":"2020-01-06","author":"唐刘","fillInMethod":"writeDirectly","customUrl":"special-week-tools-matter","file":null,"relatedBlogs":[]},{"id":"Blogs_275","title":"拥抱 Elasticsearch：给 TiDB 插上全文检索的翅膀","tags":["TiDB","Elasticsearch","全文检索"],"category":{"name":"社区动态"},"summary":"我们尝试为 TiDB 引入“全文检索”功能，为存储在 TiDB 中的文本数据提供随时随地搜索的能力。","body":"> 作者介绍：孙晓光，知乎技术平台负责人，与薛宁（@Inke）、黄梦龙（@PingCAP）、冯博（@知乎）组队参加了 TiDB Hackathon 2019，他们的项目 TiSearch 获得了 CTO 特别奖。\n\n“搜索”是大家在使用各种 APP 中非常重要的一个行为，对于知乎这样以海量优质内容为特色的产品来说，借助搜索帮助用户准确、快速地触达想要寻找的内容更是至关重要。而“全文检索”则是隐藏在简单的搜索框背后不可或缺的一项基本能力。\n\n当前我们正逐步将越来越多的业务数据向 TiDB 迁移，目前在 TiDB 上我们只能使用 SQL Like 对内容进行简单的检索。但即便不考虑性能问题，SQL Like 仍然无法实现一些在搜索场景下常见的信息检索需求，例如下图所示的几种场景，单纯使用 Like 会导致查询到有歧义的结果或满足搜索条件的结果无法返回。\n\n![1-问题](https://img1.www.pingcap.com/prod/1_87c8f4921d.png)\n\n当前 TiDB 全文检索能力的缺失，使得我们依旧需要使用传统的方式将数据同步到搜索引擎，在过程中需要根据业务特点做大量繁琐的数据流水线工作维护业务数据的全文索引。\n\n为了减少这样的重复劳动，在今年 TiDB Hackathon 中我们尝试为 TiDB 引入“全文检索”功能，为存储在 TiDB 中的文本数据提供随时随地搜索的能力。以下是最终的效果展示：\n\n![2-demo](https://img1.www.pingcap.com/prod/2_demo_1ca6dcf1ca.gif)\n\n## 方案设计\n\n要在短短一天的 Hackathon 时间内让 TiDB 中支持全文检索，难度还是非常大的，于是在最开始的时候，我们就选择了一条非常稳妥的设计方案——采用整合 [Elasticsearch](https://www.elastic.co/)（后续简称 ES）的方式为 TiDB 扩展全文检索能力。\n\n![3-tidb-and-elasticsearch](https://img1.www.pingcap.com/prod/3_tidb_and_elasticsearch_0581b9260c.gif)\n\n为什么选择 ES？一方面我们可以充分利用 ES 成熟的生态直接获得中文分词和 query 理解能力。另外生态融合所带来的强强联合效应，也符合 TiDB 崇尚社区合作的价值观。\n\n考虑到工作量，对于全文索引的数据同步方案我们没有采用 TiKV [Raft Learner](https://github.com/tikv/tikv/issues/2475) 机制，也没有使用 [TiDB Binlog](https://github.com/pingcap/tidb-binlog) 的方式进行同步，而是采用了最保守的双写机制直接在 TiDB 的写入流程中增加了全文索引更新的流程。\n\n![4-架构图](https://img1.www.pingcap.com/prod/4_0ed89da5d9.png)\n\n\n架构如上图所示，TiDB 作为 ES 和 TiKV 之间的桥梁，所有同 ES 的交互操作都嵌入在 TiDB 内部直接完成。\n\n在 TiDB 内部，我们将表额外增加了支持 FULLTEXT 索引的元数据记录，并且在 ES 上面创建了对应的索引和 [Mapping](https://www.elastic.co/cn/blog/found-elasticsearch-mapping-introduction)，对于 FULLTEXT 索引中的每一个文本列，我们都将它添加到 Mapping 中并指定好需要的 [Analyzer](https://www.elastic.co/cn/blog/found-text-analysis-part-1)，这样就可以在索引上对这些文本列进行全文检索了。\n\n在 ES 的索引的帮助下，我们只需要在写入数据或者对数据进行更新的时候在 ES 的索引上进行对应的更新操作，就保持 TiDB 和 ES 数据的同步。而对于查询，现在流程如下：\n\n1. TiDB 解析用户发送的 Query。\n2. 如果发现该 Query 带有全文检索的 hint，TiDB 则会将请求发给 ES，使用 ES 索引查询到记录主键。\n3. TiDB 拿到所有记录主键之后，在 TiDB 内部获取实际的数据，完成最终的数据读取。\n4. TiDB 将结果返回给用户。\n\n## 未来规划\n\nHackathon 短短的 24 小时，让我们验证了整合 TiDB 和 ES 的可能性，当然，我们不会满足于这套双写的方案。未来我们会参考 [TiFlash](https://medium.com/@PingCAP/delivering-real-time-analytics-and-true-htap-by-combining-columnstore-and-rowstore-1e006d3c3ef5)，基于 Raft Learner 实时将数据变更同步给 ES，将 TiDB 打造成一个真正的能支持实时全文检索的 HTAP 数据库，如下图所示：\n\n![5-未来规划](https://img1.www.pingcap.com/prod/5_2cbcfaa1ac.png)\n\n使用 Raft Learner，对于写流程：\n\n* TiDB 会直接将数据写给底层的 TiKV。\n* TiKV 会通过 Raft 协议将写入数据同步到 ES Learner 节点，通过该 Learner 节点写入到 ES。\n\n对于读流程：\n\n* TiDB 解析到用户发过来的 Query 带有全文检索的 hint。\n* TiDB 将请求发给 ES Learner 节点。\n* ES Learner 节点首先通过 Raft 协议来确保节点上面有了最新的数据，并且最新的数据已经写入到 ES。\n* ES Learner 节点通过 ES 的索引读取到对应的记录主键，返回给 TiDB。\n* TiDB 使用记录主键获取到完整的数据，并返回给客户端。\n\n可以看到，相比于之前让 TiDB 双写到 ES 和 TiKV 的方案，在写入上面，TiDB 并不需要跟 ES 进行交互，而在读取方面，通过 Raft 协议，TiDB 也能保证从 ES 读取到最新的数据，保证了数据的一致性。\n\n当然，要实现上面的功能，我们也需要更多的帮助，我们希望能够跟社区小伙伴一起，一起完成这个非常酷的特性。\n\n## 写在最后\n\n得益于个人在知乎搜索团队的短暂经历，对搜索的价值和业务接入搜索的工作量有过很直观的感受。在越来越多的数据存在于 TiDB 的时代，随时可以对业务数据的某些字段进行全文检索的价值很大。这个价值不但体现在能够实现以往 SQL 难以做好的一些事情，更大的意义是将全文检索的能力以接近 free 的方式提供给业务方，给用户搭建起一座连接关系型数据库与搜索引擎的桥梁，做到随时写入，随时搜索。如果你也有这方面的想法，欢迎邮件联系我 sunxiaoguang@zhihu.com。","date":"2019-12-10","author":"孙晓光","fillInMethod":"writeDirectly","customUrl":"fulltext-search-with-tidb-and-elasticsearch","file":null,"relatedBlogs":[]},{"id":"Blogs_258","title":"赛程刚过 1/3，什么操作让性能提升 150+ 倍？丨TiDB 性能挑战赛","tags":["TiDB 性能挑战赛","社区动态","社区"],"category":{"name":"社区动态"},"summary":"TiDB 性能挑战赛的赛程刚过 1/3，参赛选手们已经取得了十分耀眼的阶段性成果～让我们来看看吧！","body":"11 月初我们开启了一项社区新活动「TiDB 性能挑战赛」(Performance Challenge Program，简称 PCP)，这项积分赛将持续 3 个月，选手将完成一系列难度不同的任务，赢得相应的积分。目前赛程刚刚过去三分之一，已经取得了十分耀眼的阶段性成果：\n\n+ 过去一个月共吸引了来自社区的 156 位贡献者，包括：\n    - 14 支参赛队伍。\n    - 110 位个人参赛者。\n+ 参赛选手们总共完成了 147 个挑战任务，这些成果已经逐步落地到 TiDB 产品中：\n    - TiDB 表达式框架中完成了 70+ 个函数的向量化。\n    - TiKV 协处理器中完成了 40+ 个函数的向量化，其中 34 个已在 TiDB 侧新开启了下推，让下推的函数计算速度大幅上升。\n\n**截至发稿时积分排行榜前五名的参赛选手 / Team 分别是：.* team、ekalinin、mmyj、AerysNan、js00070。**\n\n其中 .* team 表现尤为优异，他们已经拿到了 4150 积分，在排行榜上遥遥领先。而来自俄罗斯的个人参赛者 ekalinin 获得了 1450 积分，是目前积分最高的个人参赛者，他共提交了 17 个任务，目前完成了 12 个，其中包含一个 Medium 难度的任务。​\n\n![积分排行榜](https://img1.www.pingcap.com/prod/1_2623bbc949.png)\n\n<div class=\"caption-center\">积分排行榜</div>\n\n>“因为对 Rust 感兴趣参加了这次 PCP，能够亲自改善一个自己会使用的工具的感受非常令人愉悦，项目的文档，代码结构和社区都非常友好,带来了很强的正反馈。”\n>\n>—— Renkai（PCP 个人参赛者）\n>\n>“参加 PCP 是很有趣的体验，既能深度参与开源项目，又能在这个过程中学到很多数据库和 Rust 的知识，还能通过获得积分兑换奖励，导师的指导非常耐心，希望能有更多的人参与进这个项目来。”\n>\n>—— TennyZhuang（PCP 团队参赛者 .* team 成员）\n\n>“I like Go & databases. TiDB has both of them. So I just decided to deep dive into internals of the TiDB and check if I can be useful for it. I'm a big fan of open source. I have a couple of open sourced projects and I understand the importance of the contribution into open source projects. \n>\n>I feel great after joining the PCP and TiDB community! Good docs, a lot of tests, well written code :)”\n>\n>—— ekalinin（PCP 个人参赛者，来自俄罗斯）\n\n**下面让我们来看看过去的一个月里大家在「性能提升」方面有哪些突破性的战绩吧！**\n\n### 1. IN() 函数性能提升 150+ 倍\n\n相关 PR [链接](https://github.com/tikv/tikv/pull/6000)，作者：[TennyZhuang](https://github.com/TennyZhuang)（ .* team ）\n\n![2-性能优化效果](https://img1.www.pingcap.com/prod/2_74d8c43634.png)\n\n`IN()` 是一个大家用的很多的 SQL 内置函数。这个 PR 使得 `IN()` 内置函数的性能有了复杂度级别的提升，从 `O(N)` 提升到 `O(1)`，如上图所示。这对于 `IN()` 函数中有很多参数的情况能有很大的帮助，例如在以下 1000 个参数场景中性能提升可达 150+ 倍：\n\n```\nCREATE TABLE `foo` (\n  `id` int(11) NOT NULL AUTO_INCREMENT,\n  `c` char(100),\n  PRIMARY KEY (`id`)\n);\n\nselect * from foo where c in (\n\"271a76b46731d9\", \"a7a69f89d4b32e\", \"8d969b6b76f6f4\", \"8ea63d5c33dabe\", \"4c5dabf74df99f\", \"897ab55a20218b\", \"80d73f4331a342\", \"a4747627a2e05d\",\n\"e20beca46373\", \"4dbc295621b4c5\", \"79ab1ea844c293\", \"86d75b32f6b1b8\", \"7fd827adcc7cd0\", \"bf26b53dd73dd\",\n...\n);\n```\n\n*大家不要觉得这么多参数是很少见的情况，实际上我们已经遇到多个 TiDB 用户给 `IN()` 内置函数传递多达几千个参数的场景。*\n\n[TennyZhuang](https://github.com/TennyZhuang)（ .* team 成员）成功通过这个 PR 获得了 2100 积分，这个是目前选手获得的单个贡献最高积分。不过这还只是 Medium 难度的任务，我们还有许多更高积分奖励的 Hard 级别任务等待大家来挑战。\n\n### 2. LIKE() 函数性能指数级提升\n\n相关 PR [链接](https://github.com/tikv/tikv/pull/5866)，作者：[TennyZhuang](https://github.com/TennyZhuang)（ .* team 成员）\n\n![3-对比结果](https://img1.www.pingcap.com/prod/3_d8ef93e7d6.png)\n\n这个 PR 通过修改了算法，实现了对 `LIKE()` 内置函数性能的指数级别改进，从 `O(2^N)` 优化到 `O(N)`。在优化前，仅仅是 6 个通配符就能将单行计算性能降低到秒级，对性能可以造成非常严重的影响。上图直观展示了这个 PR 带来的性能提升（纵坐标是对数坐标）。[TennyZhuang](https://github.com/TennyZhuang)（ .* team 成员）通过这个 PR 获得了 1500 积分。\n\n### 3. 全面提升 TPC-H 性能\n\n相关 PR [链接](https://github.com/tikv/tikv/pull/5979)，作者：[Renkai](https://github.com/Renkai)\n\n[TPC-H](http://www.tpc.org/tpch/) 是目前业界通用的衡量数据库分析处理能力的基准测试。这个任务通过减少内存复制的方式，全面提升了 TPC-H 各查询 5%~14% 的耗时，可以说是非常令人惊艳的结果了，以下是对比结果：\n\n![4-TPC-H](https://img1.www.pingcap.com/prod/4_TPC_H_d112e165de.png)\n\n下表加红加粗部分每个语句提升的百分比。\n\n![5-benchmark](https://img1.www.pingcap.com/prod/5_benchmark_b10ceb5118.png)\n\n## 更多有意思的任务\n\n目前还有更多更有挑战，更高积分的任务在等待着大家来挑战：\n\n+ [PCP-27](https://github.com/tikv/rust-rocksdb/issues/375)：通过跳过 RocksDB Compaction 阶段的某些 SST，以减少 RocksDB 写放大（积分：3600）。\n\n+ [PCP-26](https://github.com/pingcap/pd/issues/1847)：优化 PD 获取 TSO 的性能 （积分：20000）。\n\n+ [PCP-10](https://github.com/pingcap/tidb/issues/12979) ：优化宽表情况下的查询效率（积分：3000）。\n+ ……\n\n当前开放的任务列表可分别在 [TiDB Tasks](https://github.com/pingcap/tidb/projects/26)、[TiKV Tasks](https://github.com/tikv/tikv/projects/20)、[PD Tasks](https://github.com/pingcap/pd/projects/2) 中找到。\n\n更多参赛详情，可以进入 [官方网站](https://pingcap.com/community-cn/tidb-performance-challenge/) 查看。\n\n## 致谢\n\n这里也需要对各个 Special Interest Group（SIG）的 Tech Lead 以及 Mentor 表达感谢，他们为 PCP 完成了出题以及指导参赛者们完成了这些令人印象深刻的挑战：\n\n+ [breeswish](https://github.com/breeswish)（[@Coprocessor SIG](https://github.com/tikv/community/tree/master/sig/coprocessor)）\n+ [lonng](https://github.com/lonng)（[@Coprocessor SIG](https://github.com/tikv/community/tree/master/sig/coprocessor)）\n+ [sticnarf](https://github.com/sticnarf) （[@Coprocessor SIG](https://github.com/tikv/community/tree/master/sig/coprocessor)）\n+ [yiwu-arbug](https://github.com/yiwu-arbug) （[@Storage Engine SIG](https://github.com/tikv/community/tree/master/sig/engine)）\n+ [zhangjinpeng1987](https://github.com/zhangjinpeng1987)（[@Storage Engine SIG](https://github.com/tikv/community/tree/master/sig/engine)）\n+ [SunRunAway](https://github.com/SunRunAway)（@Expression SIG）\n+ [qw4990](https://github.com/qw4990)（@Expression SIG]）\n\n>[TiDB 性能挑战赛](https://pingcap.com/community-cn/tidb-performance-challenge/) 由 PingCAP 发起，旨在激发社区创造性，参赛选手可以通过完成一系列的任务提升 TiDB 产品的性能。赛事于 2019 年 11 月 4 日正式开启，将持续 3 个月，比赛任务分为三个难度：Easy、Medium、Hard，不同难度对应不同积分，参赛选手获得的积分可以兑换 TiDB 限量周边礼品等丰富的奖励。","date":"2019-12-05","author":"Yao Wei ","fillInMethod":"writeDirectly","customUrl":"pcp-report-201911","file":null,"relatedBlogs":[]},{"id":"Blogs_199","title":"TiDB Hackathon 2019 — 你呼呼大睡，机器人却在找 bug？","tags":["测试","Hackathon"],"category":{"name":"社区动态"},"summary":"复杂系统的测试是一件艰难、艰苦和艰巨的事情，可不可以让程序自动帮我们查 bug？","body":">作者介绍：我和我的 SQL 队（成员：杜沁园、韩玉博、黄宝灵、满俊朋），他们的项目「基于路径统计的 sql bug root cause 分析」获得了 [TiDB Hackathon 2019](https://pingcap.com/community-cn/hackathon2019/) 的三等奖。\n\n曾在 Hacker News 上看到过一个 Oracle 工程师处理 bug 的 [日常](https://news.ycombinator.com/item?id=1842637)：\n\n*   先花两周左右时间来理解 20 个参数如何通过神奇的组合引发 bug。\n*   改了几行代码，尝试对 bug 进行修复，提交测试集群开始跑近百万个测试 case，通常要 20~30 小时。\n*   运气好的话会有 100 多个 case 没过，有时候上千个也有可能，只好挑选几个来看，发现还有 10 个参数之前没有注意到。\n*   又过了两周，终于找到了引起 bug 的真正参数组合，并跑通了所有测试。并增加 100 多个测试 case 确保覆盖他的修改。\n*   经过一个多月的代码 review，他的修改终于合并了，开始处理下一个 bug……\n\n后来这个工程师感慨说：“I don't work for Oracle anymore. Will never work for Oracle again!”\n\nOracle 12.2 有将近 2500 万行 C 代码，复杂系统的测试是一件艰难、艰苦和艰巨的事情。而测试一个分布式数据库的情况就更复杂了，我们永远不知道用户可能写出什么样的 SQL，表结构和索引有多少种组合，此外还要考虑集群在什么时候节点发生宕机，以及受到网络抖动、磁盘性能退化等因素的影响，可能性几乎是无限的。\n\n**那么能不能写个机器人自动帮我们查 bug 呢？**\n\n这似乎是个不错的主意，带着这个想法我们组了团队，来参加 [TiDB Hackathon 2019](https://pingcap.com/community-cn/hackathon2019/) 比赛，并意外地斩获了三等奖。\n\n## 如何做到「睡觉的时候让程序自动定位 bug」？\n\n项目的思路其实很简单，如果在跑测试 case 的时候能够用统计学的方法对足够多次实验的代码路径进行分析，就可以找出疑似 bug 的代码，最终结果以代码染色的方式由前端可视化呈现，就得到了如下图展示的效果：\n\n![最终效果](https://img1.www.pingcap.com/prod/1_demo_86ece8a9c6.gif)\n\n这是我们在 Hackathon 比赛中针对一个 TiDB 的 [PR](https://github.com/pingcap/tidb/pull/12476) 所做的实验，颜色越深，亮度越高表示包含错误逻辑的可能性越大。该方法不仅适用于数据库系统的测试，同样适用于其他任何复杂的系统。\n\n## 背后的原理\n\n项目最初是受到 VLDB 的一篇论文的启发 [APOLLO: Automatic Detection and Diagnosis of Performance Regressions in Database Systems](http://www.vldb.org/pvldb/vol13/p57-jung.pdf)，在此感谢一下乔治亚理工学院和 eBay 公司的几位作者。该论文主要围绕如何诊断引发数据库性能回退的代码，其核心思想也同样适用于排查 bug。论文中提到的自动诊断系统由 SQLFuzz，SQLMin 和 SQLDebug 三个模块组成。\n\n![论文中的自动诊断系统结构](https://img1.www.pingcap.com/prod/2_2a5790020d.png)\n\n*   SQLFuzz：负责随机生成 SQL，并利用二分查找定位到性能回退的前后两个版本，传递给 SQLMin 模块。\n*   SQLMin：通过剪枝算法将 SQLFuzz 生成的 SQL 进行化简，得出能够复现该问题的最小 SQL ，传递给 SQLDebug 模块。目的是减少无关的代码路径，降低噪音。\n*   SQLDebug：对源码进行插桩，使其在执行 SQL 时能够输出代码的执行路径。然后对两个版本的代码路径进行分析，建立一个统计模型来定位问题的位置。\n\n最终系统自动生成测试报告，内容包含：\n\n*   哪一次的代码 commit 引入了性能回退。\n*   存在问题的代码源文件。\n*   具体的函数位置。\n\n而实际上，考虑到并发、循环、递归等带来的影响，代码执行路径分析会非常复杂。为了保证能够在 Hackathon 那么短的时间内展示出效果，我们又参考了另一篇论文 [Visualization of Test Information to Assist Fault Localization](https://www.cc.gatech.edu/~john.stasko/papers/icse02.pdf)，其核心思想是通过统计代码块被正确和错误测试用例经过次数，再基于分析算法来涂上不同的颜色，简单而实用。\n\n![染色效果](https://img1.www.pingcap.com/prod/3_e212e82375.png)\n\n其实借助这个思路也可以应用到其他领域，后面我们将展开来介绍。接下来我们先来看看 SQLDebug 是如何实现的。\n\n## 聊聊细 (gān) 节 (huò)\n\n### 如何自动产生测试 case？\n\n由于是基于统计的诊断，我们需要先构建足够多的测试用例，这个过程当然最好也由程序自动完成。事实上，grammar-based 的测试在检验编译器正确性方面有相当长的历史，DBMS 社区也采用类似的方法来验证数据库的功能性。比如：微软的 SQL Server 团队开发的 [RAGS](http://vldb.org/conf/2007/papers/industrial/p1243-bati.pdf) 系统对数据库进行持续的自动化测试，还有社区比较出名的 [SQLSmith](https://github.com/anse1/sqlsmith) 项目等等。今年 TiDB  Hackathon 的另一个获奖项目 [sql-spider](https://github.com/zyguan/sql-spider) 也是实现类似的目的。\n\n这里我们暂时采用 PingCAP 开源的随机测试框架 [go-randgen](https://github.com/pingcap/go-randgen) 实现 SQL fuzzing，它需要用户写一些规则文件来帮助生成随机的 SQL 测试用例。规则文件由一些 SQL 语法表达式组成。randgen 每次从 query 开始随机游走一遍 SQL 表达式的语法树，生成一条 SQL，产生一条像下图红线这样的路径。\n\n![路径](https://img1.www.pingcap.com/prod/4_16d5d526ce.png)\n\n我们将每个语法表达式生成正确与错误用例的比例作为它的颜色值，绘制出 SQLFuzz 的展示页面。通过该页面，就可以比较容易地看出哪条表达式更容易产生错误的 SQL。\n\n![sqlfuzz](https://img1.www.pingcap.com/prod/5_sqlfuzz_b21ea1e14a.gif)\n\n### 代码跟踪\n\n为了跟踪每一条 SQL 在运行时的代码执行路径，一个关键操作是对被测程序进行插桩 (Dynamic Instrumentation)。VLDB 论文中提到一个二进制插桩工具 [DynamoRIO](https://www.dynamorio.org/)，但是我们用了另外一个思路，为什么不在编译之前直接对源码进行插桩呢？\n\n参考 [go cover tool](https://github.com/golang/tools/blob/master/cmd/cover/cover.go) 的实现，我们写了一个专门的代码插桩工具 [tidb-wrapper](https://github.com/fuzzdebugplatform/tidb-wrapper)。它能够对任意 TiDB 源码进行处理，生成一份 [wrapped](https://github.com/DQinYuan/tidb-v3.0.0-wrapped) 代码，并且在程序中注入一个 HTTP Server，假设某条 SQL 的摘要是 `df6bfbff`（这里的摘要指的是 SQL 语句的 32 位 MurmurHash 计算结果的十六进制，主要目的是简化传输的数据），那么只要访问 `http://<tidb-server-ip>::43222/trace/df6bfbff` 就能获得该 SQL 所经过的源码文件和代码块信息。\n\n```\n// http://localhost:43222/trace/df6bfbff\n\n{\n  \"sql\": \"show databases\",\n  \"trace\": [\n    {\n      \"file\": \"executor/batch_checker.go\",\n      \"line\": null\n    },\n    {\n      \"file\": \"infoschema/infoschema.go\",\n      \"line\": [\n        [\n          113,\n          113\n        ],\n        [\n          261,\n          261\n        ],\n       //....\n    }\n   ],\n}\n```\nline 字段输出的每个二元组都是一个基本块的起始与结束行号（左闭右闭）。基本块的定义是绝对不会产生分支的一个代码块，也是我们统计的最小粒度。那是如何识别出 Go 代码中基本块的呢？其实工作量还挺大的，幸好 Go 的源码中有这一段，我们又刚好看到过，就把它裁剪出来，成为 [go-blockscanner](https://github.com/DQinYuan/go-blockscanner)。\n\n因为主要目标是正确性诊断，所以我们限定系统不对 TiDB 并发执行 SQL，这样就可以认为从 `server/conn.go:handleQuery` 方法被调用开始，到 SQLDebug 模块访问 trace 接口的这段时间所有被执行的基本块都是这条 SQL 的执行路径。当 SQLDebug 模块访问 HTTP 接口，将会同时删除该 SQL 相关的 trace 信息，避免内存被撑爆。\n\n### 基本块统计\n\nSQLDebug 模块在获取到每条 SQL 经过的基本块信息后，会对每个基本块建立如下的可视化模型。\n\n**首先是颜色，经过基本块的失败用例比例越高，基本块的颜色就越深。**\n\n\n![formula-1](https://img1.www.pingcap.com/prod/6_formula_1_be6489544e.png)\n\n**然后是亮度，经过基本块的失败用例在总的失败用例中占的比例越高，基本块的亮度越高。**\n\n![formula-2](https://img1.www.pingcap.com/prod/7_formula_2_b6a4dc60b6.png)\n\n已经有了颜色指标，为什么还要一个亮度指标呢？其实亮度指标是为了弥补“颜色指标 Score”的一些偏见。比如某个代码路径只被一个错误用例经过了，那么它显然会获得 Score 的最高分 1，事实上这条路径不那么有代表性，因为这么多错误用例中只有一个经过了这条路径，大概率不是错误的真正原因。所以需要额外的一个亮度指标来避免这种路径的干扰，**只有颜色深，亮度高的代码块，才是真正值得怀疑的代码块。**\n\n上面的两个模型主要是依据之前提到的 Visualization 的论文，我们还自创了一个文件排序的指标，失败用例在该文件中的密度越大（按照基本块），文件排名越靠前：\n\n![formula-3](https://img1.www.pingcap.com/prod/8_formula_3_5535ec2dd5.png)\n\n前端拿到这些指标后，按照上面计算出的文件排名顺序进行展示，越靠前的文件存在问题的风险就越高。\n\n![formula-4](https://img1.www.pingcap.com/prod/9_formula_4_487dd8592f.png)\n\n当点击展开后可以看到染色后的代码块：\n\n![染色后的代码块](https://img1.www.pingcap.com/prod/10_6745c49ee1.png)\n\n**我们经过一些简单的实验，文件级别的诊断相对比较准确，对于基本块的诊断相对还有些粗糙，这跟没有实现 SQLMin 有很大关系，毕竟 SQLMin 能去除不少统计时的噪声。**\n\n## 还能不能做点别的？\n\n看到这里，你可能觉得这个项目不过是针对数据库系统的自动化测试。而实际上借助代码自动调试的思路，可以给我们更多的启发。\n\n### 源码教学\n\n阅读和分析复杂系统的源码是个头疼的事情，TiDB 就曾出过 [24 篇源码阅读系列文章](https://pingcap.com/blog-cn/#TiDB-%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB)，用一篇篇文字为大家解读源码​，江湖人称 “二十四章经”。那么是否可以基于源码的可视化跟踪做成一个通用工具呢？这样在程序执行的同时就可以直观地看到代码的运行过程，对快速理解源码一定会大有帮助。更进一步，配合源码在线执行有没有可能做成一个在线 web 应用呢？\n\n### 全链路测试覆盖统计\n\n语言本身提供的单测覆盖统计工具已经比较完备了，但一般测试流程中还要通过 e2e 测试、集成测试、稳定性测试等等。能否用本文的方法综合计算出各种测试的覆盖度，并且与 CI 系统和自动化测试平台整合起来。利用代码染色技术，还可以输出代码执行的热力图分析。结合 profiler 工具，是不是还可以辅助来定位代码的性能问题？\n\n![全链路测试覆盖统计](https://img1.www.pingcap.com/prod/11_9ff6f36307.png)\n\n### Chaos Engineering\n\n在 [PingCAP](https://pingcap.com/) 内部有诸多的 [Chaos](https://www.infoq.cn/article/EEKM947YbboGtD_zQuLw) 测试平台，用来验证分布式系统的鲁棒性，譬如像 [Jepsen](https://github.com/jepsen-io/jepsen) ，还有 PingCAP 自研的薛定谔稳定性测试系统等。混沌工程测试比较困扰的一点是，当跑出问题之后想再次复现就很难，只能通过当时的情形去猜代码可能哪里有问题。如果能在程序运行时记录代码的执行路径，根据问题发生时间点附近的日志和监控进一步缩小范围，再结合代码执行路径分析就能精确快速的定位到问题的原因。\n\n### 与分布式 Tracing 系统集成\n\nGoogle 有一篇论文是介绍其内部的 [分布式追踪系统 Dapper](https://ai.google/research/pubs/pub36356) ，同时社区也有比较出名的项目 [Open Tracing](https://opentracing.io/) 作为其开源实现，Apache 下面也有类似的项目 [Skywalking](https://skywalking.apache.org/)。一般的 Tracing 系统主要是跟踪用户请求在多个服务之间的调用关系，并通过可视化来辅助排查问题。但是 Tracing 系统的跟踪粒度一般是服务层面，如果我们把 `trace_id` 和 `span_id` 也当作标注传递给代码块进行打桩，那是不是可以在 Tracing 系统的界面上直接下钻到源码，听起来是不是特别酷？\n\n## 接下来的工作\n\n因为 Hackathon 时间有限，我们当时只完成了一个非常简单的原型，距离真正实现睡觉时程序自动查 bug 还有一段路要走，我们计划对项目持续的进行完善。\n\n接下来，首先要支持并行执行多个测试用例，这样才能在短时间得到足够多的实验样本，分析结果才能更加准确。另外，要将注入的代码对程序性能的影响降低到最小，从而应用于更加广泛的领域，比如性能压测场景，甚至在生产环境中也能够开启。\n\n看到这里可能你已经按耐不住了，附上 [项目的完整源码](https://github.com/fuzzdebugplatform/fuzz_debug_platform)，Welcome to hack!","date":"2019-12-03","author":"我和我的 SQL 队","fillInMethod":"writeDirectly","customUrl":"sqldebug-automatically","file":null,"relatedBlogs":[]},{"id":"Blogs_154","title":"TiDB Hackathon 2019 — 流量和延迟减半！挑战 TiDB 跨数据中心难题","tags":["跨数据中心","Hackathon"],"category":{"name":"社区动态"},"summary":"我们针对 TiDB 跨数据中心方案做了一些优化，使得跨地域 SQL 查询延迟下降 50%，跨节点消息数减半，即网络流量减半。","body":">作者介绍：.* team（成员：庄天翼、朱贺天、屈鹏、林豪翔）参加了 [TiDB Hackathon 2019](https://pingcap.com/community-cn/hackathon2019/)，他们项目「TiDB 跨数据中心方案的优化」斩获了二等奖。\n\n众所周知，在对可用性要求极高的行业领域（比如金融、通信），分布式数据库需要跨地域的在多个数据中心之间建立容灾以及多活的系统架构，同时需要保持数据完整可用。但这种方式同时也带来了一些问题：\n\n1. 跨地域的网络延迟非常高，通常在几十毫秒左右，洲际间更能达到几百毫秒。\n2. 跨地域的网络专线带宽昂贵、有限，且难于扩展。\n\n在今年 TiDB Hackathon 的比赛过程中，我们针对以上问题做了一些有趣的事情，并获得如下优化成果：\n\n1. 跨地域 SQL 查询，延迟下降 50%（图 1）。\n2. 跨节点消息数减半，即网络流量减半（图 2）。\n\n![图 1 延迟对比](https://img1.www.pingcap.com/prod/1_303a22cce9.png)\n\n<div class=\"caption-center\">图 1 延迟对比</div>\n\n![图 2 网络流量对比](https://img1.www.pingcap.com/prod/2_f29ad09144.png)\n\n<div class=\"caption-center\">图 2 网络流量对比</div>\n\n>“Google Spanner 高性能事务和强一致特性（跨区域甚至跨洲），是每一个做多数据中心架构设计的工程师心中所向往的目标。虽然当前 TiDB 在多数据中心部署时的表现同 Google Spanner 还有明显的差距，但我们很高兴的看到“多数据中心读写优化”项目让 TiDB 向 Spanner 级别多数据中心能力迈出了坚实的一步。相信在社区小伙伴们的共同努力下，假以时日 TiDB 一定能够为大家带来 Google Spanner 级别的体验。”\n>\n>—— 孙晓光（知乎｜技术平台负责人）\n>\n>“在官方推荐的具备同城多活能力的同城三中心五副本，以及两地三中心五副本的部署方案中，三个数据中心按照 2:2:1 的方式分配副本，网络租用成本是该架构的主要投入，我们在一次压力测试过程中，曾遇到过在极致的压力下占满网络带宽的情况。这个项目显著优化了两机房之间的带宽占用，可以为客户节约更多的成本。”\n>\n>—— 秦天爽（PingCAP｜技术支持总监）\n\n接下来我们将从技术原理分析是如何做到以上优化效果的。以下内容需要读者具备 [Raft 一致性协议](https://raft.github.io/) 的一些预备知识，如果大家准备好了，就继续往下看吧～\n\n## 技术原理\n\n考虑一个两数据中心的部署方案（如图 3 所示），左半部分为主数据中心（Master DC，假设在北京）TiKV 和 PD 的多数副本都部署在这里，并且很重要的是 Leader 会被固定在这里；图 3 右半部分为从数据中心（Slave DC，假设在西安）里面有 TiKV 和 TiDB。用户只会在主数据中心进行数据写入，但会在两边都进行数据读取。\n\n![图 3 主数据中心 & 从数据中心部署](https://img1.www.pingcap.com/prod/3_b9c9d93bbe.png)\n\n<div class=\"caption-center\">图 3 主数据中心 & 从数据中心部署</div>\n\n### Follower Read Improvement\n\n在 TiDB 里面，当我们需要从西安这边读取数据的时候，一个典型的流程如下：\n\n1.  西安的 TiDB 向北京的 PD 发起获取 TSO 请求，得到一个 `start_ts`（事务开始阶段的 ID）。（1 RTT）\n\n2.  西安的 TiDB 为涉及到的每个 Region 向北京的 TiKV Leader 节点发起多个（并行）读请求（如图 4）。（1 RTT）\n\n>名词解释：\n>\n>* RTT（Round-Trip Time），可以简单理解为发送消息方从发送消息到得知消息到达所经过的时间。\n>* TSO（Timestamp Oracle），用于表示分布式事务开始阶段的 ID。\n\n![图 4 不启用 Follower Read 的读流程](https://img1.www.pingcap.com/prod/4_Follower_Read_de50c21e8e.png)\n\n<div class=\"caption-center\">图 4 不启用 Follower Read 的读流程</div>\n\n可以看到，虽然西安本地也有 TiKV 副本数据，但完全没有参与这个过程。该实现存在两个问题：\n\n*   跨地域网络宽带占用大。\n\n*   延迟高（2 RTT）。\n\n下面我们分别阐述对这两个问题的优化思路。\n\n#### 1. 跨地域网络宽带占用大\n\n其实针对这个问题，TiDB 已经在 3.1 版本引入了 [Follower Read](https://pingcap.com/blog-cn/follower-read-the-new-features-of-tidb/) 特性。开启该特性后，TiKV Leader 上的节点从必须处理整个读请求改为只用处理一次 read_index 请求（一次 read_index 通常只是位置信息的交互，不涉及数据，所以轻量很多），负载压力大幅降低，是一个很大的优化，如下图所示。\n\n![图 5 开启 Follower Read 的读流程](https://img1.www.pingcap.com/prod/5_Follower_Read_fa12faf0a4.png)\n\n<div class=\"caption-center\">图 5 开启 Follower Read 的读流程</div>\n\n#### 2. 延迟高\n\n在读延迟上，TiDB 仍然需要 2 个跨地域的 RTT。这两个 RTT 的延迟是由一次获取 TSO 请求和多次（并行的）`read_index` 带来的。简单观察后，我们不难发现，我们完全可以将上面两个操作并行一起处理，如下图所示。\n\n![图 6 Follower Read 流程优化](https://img1.www.pingcap.com/prod/6_Follower_Read_96bc58c9db.png)\n\n<div class=\"caption-center\">图 6 Follower Read 流程优化</div>\n\n通过这种优化方式，我们实现了跨数据中心读请求 2RTT -> 1RTT 的提升，并且我们在模拟的高延迟网络环境中的 benchmark 证实了这一点：\n\n![图 7 benchmark](https://img1.www.pingcap.com/prod/7_benchmark_21dd04c029.png)\n\n<div class=\"caption-center\">图 7 benchmark</div>\n\n考虑到没有原子钟的情况下想要保证线性一致性，一次获取 TSO 的请求是无法避免的，因此可以认为 1RTT 已经是在目前的架构下最优的解决方案了。\n\n### 用 Follower Replication 减少带宽成本\n\n接下来谈一谈如何用 Follower Replication 这种方式，减少跨数据中心的带宽成本。\n\n众所周知 TiKV 集群中的一致性是依靠 Raft 协议来保证的。在 Raft 协议中，所需要被共识一致的数据可以用 Entry 来表示。一个 Entry 被共识，需要 Leader 在接收到请求之后，广播给其他 Follower 节点，之后通过不断的消息交互来使这个 Entry 被 commit。这里可能会遇到一个问题：有些时候 TiKV 被部署在世界各地不同的数据中心中，数据中心之间的网络传输成本和延迟比较高，然而 Leader 只有一个，可想而知会发生很多次跨数据中心的消息传输。\n\n举个例子，生产环境中可能需要 5 个副本来保证可用性，假设 3 个副本在北京分别是 A B C，2 个在西安分别是 D E，同时 Leader 为 A，那么一条 Entry 需要北京的 Leader A，广播给西安的 DE，那么这次广播至少需要两次跨数据中心的网络传输，如下图所示。\n\n![图 8 正常的消息广播](https://img1.www.pingcap.com/prod/8_781b975aac.png)\n\n<div class=\"caption-center\">图 8 正常的消息广播</div>\n\nFollower Replication 的目标是将这个多次的跨数据中心传输尽量减少。要实现 Follower Replication，最关键的是需要让 Leader 节点知道所有 Raft 节点与它所在的 数据中心的信息。这里我们引入了一个新概念 Group，每一个 Raft 节点都有一个对应的 Group ID，拥有相同 Group ID 的节点即在同一个数据中心中。既然有了每个 Raft 节点的 Group 信息，Leader 就可以在广播消息时在每一个 Group 中选择一个代理人节点（我们称为 Follower  Delegate），将整个 Group 成员所需要的信息发给这个代理人，代理人负责将数据同步给 Group 内的其他成员，如下图所示。\n\n![图 9 选择代理人之后的消息广播](https://img1.www.pingcap.com/prod/9_51e98afa60.png)\n\n<div class=\"caption-center\">图 9 选择代理人之后的消息广播</div>\n\n通过使用 Follower Replication，Leader 减少了一半的数据发送，既大大降低了跨数据中心带宽的压力，同时也减少了 Leader 在发送网络消息上的开销。当然，实际 Follower Replication 的实现还是很复杂的，我们后续会专门写一篇详细的文章来介绍。\n\n关于这个对 Raft 实现的改进，我们已经提交了 RFC 和实现的 PR，后续也会贡献给 etcd，感兴趣的同学可以参考：\n\n*   [https://github.com/tikv/rfcs/pull/33](https://github.com/tikv/rfcs/pull/33)\n\n*   [https://github.com/tikv/raft-rs/pull/249/](https://github.com/tikv/raft-rs/pull/249/)\n\n*   [https://github.com/etcd-io/etcd/issues/11357](https://github.com/etcd-io/etcd/issues/11357)\n\n## 总结\n\n除了我们在 Hackathon 做的两个优化，跨数据中心的场景有更多需要解决的问题和可以优化的点，我们的优化也远非最终实现，一些不难想到的优化还有：\n\n1.  Follower Read Improvement 能将一个非交互式的读事务从 2RTT 降到 1RTT，但对于交互式的读事务，由于事先不知道涉及到事务的 Region，无法预读整个读请求中所有 Region `read_index`，因此只有第一次读请求和 `get_tso` 可以并行，将 n+1 RTT 优化到了 n RTT（n 为交互式事务中读语句的数量），而如果我们能将 ts 和 committed index 的对应关系找到，并且定期维护每个 Region 的 safe ts（小于该 ts 的事务一定已经 committed or aborted），那么我们就可以将交互式读事务的延迟也降低到 1RTT。\n\n2.  跨数据中心的读请求一个很常见的场景是并不需要是最新的数据，应该提供怎么样的语义来让这种场景下的读请求完全在本地 0RTT 地读取数据，真正做到对主数据中心无依赖，做到数据中心级别的 scalability。\n\n有句话是这样说的，“对于基础架构方向的软硬件工程师而言，世界上最远的距离，是你在联通，我在电信 :D”软件工程师做得越好，秃顶的硬件工程师就越少。希望我们的项目在切实落地之后，能够大幅优化 TiDB 跨地域数据中心的延迟和网络流量，让 TiDB 能够满足更多用户的需求，成为分布式数据库领域的事实标准。","date":"2019-11-29","author":".* team","fillInMethod":"writeDirectly","customUrl":"geographic-data-distribution-traffic-and-latency-halved","file":null,"relatedBlogs":[]},{"id":"Blogs_144","title":"TiKV Engine SIG 成立，硬核玩家们看过来！","tags":["TiKV","社区","存储引擎"],"category":{"name":"社区动态"},"summary":"TiKV Engine SIG 主要职责是对 TiKV 的存储引擎的未来发展进行讨论和规划，并进行相关开发和维护。期待社区伙伴们的支持和贡献～","body":"TiKV 是一个开源项目，我们一直都欢迎和感激开源社区对 TiKV 所作出的贡献。但我们之前对开源社区的合作主要是在代码审阅和散落在各种社交媒体的线下讨论，开发者并没有合适的途径去了解和影响 TiKV 的开发计划。怎么才能更好的帮助大家找到组织，更好地参与到 TiKV 的开发中来呢？我们的设想是搭建公开的平台，邀请对 TiKV 中特定领域感兴趣的开发者加入其中，与我们一起探讨和推进相应工作。Special Interest Group（SIG）就是这样的平台。\n\nTiKV Engine SIG 是继 [Coprocessor SIG](https://pingcap.com/blog-cn/tikv-coprocessor-sig/) 之后成立的第二个 TiKV SIG 社区组织，主要职责是对 TiKV 的存储引擎的未来发展进行讨论和规划，并进行相关开发和维护。\n\n目前 TiKV 仅支持默认存储引擎 RocksDB，但是通过扩展接口，希望未来 TiKV 可以支持更多的存储引擎，我们也期待这部分工作可以得到社区的支持，在社区的讨论和贡献中得到更好的完善。此外，Engine SIG 也会对已有的存储引擎进行相关的开发和完善工作。\n\nEngine SIG 的工作主要涉及的模块包括：\n\n*   Engine Trait： TiKV 中存储引擎的抽象层。\n*   RocksDB：包括维护 TiKV 所使用的 RocksDB 分支，以及 rust-rocksdb 封装。\n*   Titan：提供 KV 分离支持的 RocksDB 存储引擎插件。\n*   未来 TiKV 对其它存储引擎的支持。\n\n## 如何加入 Engine SIG\n\n无论你是数据库开发新手，希望通过实战了解存储开发相关知识；​还是 TiKV 资深用户，希望扩展 TiKV 的能力以应用到生产环境，Engine SIG 都欢迎你的加入！\n\n有兴趣的开发者可以浏览 Engine SIG 文档并加入 Engine SIG 的 Slack 频道。Engine SIG 希望能够帮助 Contributor 逐渐成长为 Reviewer，Committer 乃至 TiKV 的 Maintaner。\n\n* Engine SIG 主页：[https://github.com/tikv/community/tree/master/sig/engine](https://github.com/tikv/community/tree/master/sig/engine)\n\n* Engine SIG 章程：[https://github.com/tikv/community/blob/master/sig/engine/constitution-zh_CN.md](https://github.com/tikv/community/blob/master/sig/engine/constitution-zh_CN.md)\n\n* Engine SIG Slack：加入 tikv-wg.slack.com 并进入 [#engine-sig](https://tikv-wg.slack.com/?redir=%2Fmessages%2Fengine-sig) 频道。\n\n## 近期工作计划\n\n近期 Engine SIG 工作会围绕在对 TiKV 已有存储引擎的改进上面，但我们会尽量选取一些对以后引入其它存储引擎也有意义的工作。具体有以下几方面：\n\n*   使用 [Bindgen](https://rust-lang.github.io/rust-bindgen/) 对 [rust-rocksdb](https://github.com/tikv/rust-rocksdb) 进行重构，减少新增存储引擎接口的开发复杂度。\n*   扩展 [failpoint](https://pingcap.com/blog-cn/tikv-source-code-reading-5/) 接口，允许为不同的存储引擎开发相应的插件，使得 TiKV 测试能够对存储引擎内部进行错误注入。\n*   [Titan](https://github.com/pingcap/titan) 存储引擎插件的性能和功能的改进。\n\n详细任务列表见：[https://github.com/tikv/tikv/projects/22](https://github.com/tikv/tikv/projects/22)。\n\n## 未来工作计划\n\n未来 Engine SIG 会更多关注于为 TiKV 引入新的存储引擎。这上面可以做的工作很多。比如说，我们可以考虑为 TiKV 引入针对不同硬件（纯内存、持久化内存、云盘等）的存储引擎，不同数据结构的存储引擎（B-Tree 引擎等），针对特殊场景的存储引擎（全文搜索等），或者单纯是不一样的存储引擎实现（LevelDB 等）。这些工作非常需要社区的参与。我们希望这些工作未来能够扩展 TiKV 的领域和可能。目前 TiKV 正在加紧对存储引擎抽象 Engine Trait 进行开发，使以上的设想成为可能。\n\n期待社区伙伴们的加入！欢迎在 Slack [#engine-sig](https://tikv-wg.slack.com/?redir=%2Fmessages%2Fengine-sig) 中与我们交流！如果对于流程或技术细节有任何疑问，都可在 channel 中讨论～","date":"2019-11-28","author":"Yi Wu","fillInMethod":"writeDirectly","customUrl":"tikv-engine-sig-introduction","file":null,"relatedBlogs":[]},{"id":"Blogs_149","title":"开源社区怎么玩？明星项目 TiKV 的 Maintainer 这样说……","tags":["社区","社区动态"],"category":{"name":"社区动态"},"summary":"“当你持续的认真投入到开源后，项目和社区就会产生双向的交流，不再只是你单向的投入，社区也会给予你反哺，这时就会形成正向循环，对项目发展会起到非常大的推动作用。”","body":"知乎技术平台团队负责人孙晓光有一个新的身份：开源分布式事务 Key-Value 数据库 TiKV项目的 Maintainer。Maintainer 是 TiDB/TiKV 开源社区的角色之一，是社区中较高级别的代码贡献者，项目的规划和设计者，拥有合并主干分支的权限。一般来说从开始贡献代码的 Contributor 成长为 Maintainer，最明显的变化是，对项目有更全局、深入的了解，对项目未来的发展也有独到、准确的见解。\n\n孙晓光觉得，其实从 Contributor 到 Committer 再到最后成为 Maintainer 这个过程，最大的感受是自己逐渐融入到了 TiKV 社区中，真正有了归属感。今天我们就带着 TiDB/TiKV 社区伙伴们的期待，和孙晓光聊了聊，打探了一下他成为 Maintainer 的经历，以及对 TiKV 社区未来的想法。\n\n## 初识：寻找原生的分布式存储方案\n\n***> 与 TiKV 项目初识，其实是带着明确的目标的。***\n\n孙晓光 2007 年毕业回国，当时国内刚开始做云，他进入一家做私有云的公司，从事私有云相关产品开发工作 7 年多时间，他坦言，这段工作经历让他个人积累了许多云相关底层系统的工作经验，这也是他对平台类技术比较感兴趣的核心原因。2017 年孙晓光加入知乎。\n刚到知乎时，他负责已读服务的开发，知乎的存储层采用的还是 MySQL 分库分表技术方案。“项目上线后，就我个人而言是难以接受这种方案的，于是我就开始寻找原生的分布式存储系统来替代它。借此机会我尝试了 TiKV，在测试的过程中我发现一些性能有改善的空间，于是我就边测试边上手做了一些优化工作，最后提了一个大 PR 上去。PR 提出后，PingCAP 首席架构师唐刘很快就跟我建立了联系，慢慢的我也进入到了 TiKV 社区当中。这就是我第一次接触 TiKV 的经历。”\n\n## 更加理解「开源社区」\n\n\n***> 我对开源社区的理解更加清晰了。***\n\n孙晓光以前也用过很多开源软件，但是当时并没有深刻理解开源的价值。**开源的第一目标应该是对别人有帮助、有价值，这个目标就已经拦住了无数的开源项目**。很多项目仅仅把代码开放出来，但是没有任何后续的支持与维护，在这样的情况下社区是无法发展的，自然也难以为他人创造价值。\n\n![孙晓光 GitHub ID](https://img1.www.pingcap.com/prod/1_Git_Hub_ID_e278ef3db5.png)\n\n“**其实当你持续的认真投入到开源后，项目和社区就会产生双向的交流，不再只是你单向的投入，社区也会给予你反哺，这时就会形成正向循环，对项目发展会起到非常大的推动作用**。我对开源的理解正是在 TiKV 社区慢慢建立起来的，TiKV 有一个非常开放友好的社区，PingCAP 和社区伙伴们热心的帮助及鼓励让我切身感受到活跃的开源社区所具有的独特魅力。在参与共建社区的过程中，我不但学习到了如何同开源社区中众多优秀的贡献者更加高效的交流，同时也对开源的价值理念和开源在基础软件领域的重大意义有了更加深入的理解。”\n\n## 「持续贡献，长期活跃」的动力何在？\n\n***> 硬核的项目 + 开放的氛围***\n\n过去多年在云方向的工作经历让孙晓光坚定的相信，云是未来的趋势，而 TiKV 作为云原生架构中承载状态的基石组件，它的重要程度毋庸置疑。作为一个技术控，TiKV 这样一个既硬核口碑又很好的项目很自然地吸引着他。同时 TiKV 社区互帮互助、开放共赢的良好氛围也是孙晓光持续参与社区建设的重要动力。\n\n“之前也为其他开源项目做过贡献，可能是这些项目对社区建设并没有投入太多精力，大部分的 PR 合并完成就没有后续了。但是在 TiKV 社区，我感受到当我参与社区后，后续会有很多追踪的动作，这会激励我保持兴趣，持续在社区中去做贡献。同时在这个过程中，我也在社区中学习了很多知识，得到了很多帮助，这也是我长期坚持在 TiKV 社区中保持活跃的一个重要原因。”\n\n迄今为止，孙晓光已经为 TiDB/TiKV 项目贡献了 18 个 PR，[推动了 TiKV  重要功能 Follower Read 的开发和落地](https://pingcap.com/blog-cn/zhihu-the-story-of-contributing-to-tidb-community/)，这个功能同时也解决了知乎业务场景中极端热点数据访问的吞吐问题。他在一年中完成了 Contributor -> Committer -> Maitainer 的角色升级，可谓是开挂式的速度，但他并没有就此止步，而是开启了一个新的挑战。\n\n## 新的挑战\n\n今天 TiKV Engine SIG（SIG = Special Interest Group）正式成立，这是 TiKV 项目成立的第二个 SIG 社区组织，孙晓光将作为第一个非 PingCAP 的 SIG TechLead，将与其他 TechLead 一起，组织大家推动 TiKV Engine 的相关开发和完善。\n\n对于 TiKV Engine SIG，孙晓光非常兴奋。\n\n“我认为 TiKV 非常适合 SIG 这个模式，因为 TiKV 是一个非常庞大且复杂的系统，进入的门槛很高，并且它还在以飞快的速度继续演进着。在这样一个庞大的系统里，想让大家参与进来其实是非常有难度的。**但 SIG 可以为大家创造一个更容易参与的小环境，且在这个小环境中是有组织有领导的，有人会帮助大家指方向，指导大家要做什么样的事情，这样一方面降低社区参与 TiKV 建设的门槛，另外一方面也可以更好的将对特定领域有经验且感兴趣的伙伴们聚集起来，高效的推进 TiKV 每一个关键方向的前进速度。**\n\n在我个人看来，存储引擎是 TiKV 中最关键的组件之一，它影响着整个系统的稳定性、功能特性以及性能表现。相信 Engine SIG 成立后，我们可以清晰的定义存储引擎同 TiKV 其它部分的契约，提供强大且易用的存储引擎抽象，借助 TiKV 完备的分布式能力，我们可以为 TiKV 拓展更多的领域和可能。”\n\nTiKV Engine SIG 是主要职责是对 TiKV 的存储引擎的未来发展进行讨论和规划，并进行相关开发和维护。目前 TiKV 仅支持默认存储引擎 RocksDB，但是通过扩展接口，希望未来 TiKV 可以支持更多的存储引擎。近期 Engine SIG 的工作会围绕在对 TiKV 已有存储引擎的改进上面。\n\n>*关于 TiKV Engine SIG  的更多信息，感兴趣的朋友们可以查看 [这篇文章](https://pingcap.com/blog-cn/tikv-engine-sig-introduction)，也可以加入 Slack [#engine-sig](https://tikv-wg.slack.com/?redir=%2Fmessages%2Fengine-sig\n) 和孙晓光等社区伙伴们一起讨论。*\n\n## 期望\n\n作为 TiKV & TiDB 重度粉丝，孙晓光希望在未来能更好的促进「知乎」和 TiKV 社区的共建。一方面依托 TiKV 社区的进步为「知乎」的业务发展提供更好的支撑基础，同时希望能够基于「知乎」的业务场景为 TiKV 的发展提供足够大的施展空间。\n\n“我非常希望我们的团队也能够真正参与进来，成为社区的贡献者。相信未来 TiKV 能够保持开放共赢的风格，建设更成熟更大规模的社区。我们这些社区伙伴会一起推动 TiKV 的高速持续发展，让 TiKV 成为未来有状态系统基石的第一选择。” \n\n\n>![TiKV Logo](https://img1.www.pingcap.com/prod/2_Ti_KV_Logo_8b5e5475cc.jpg)\n>\n>TiKV 是一个开源的分布式事务 Key-Value 数据库，支持跨行 ACID 事务，同时实现了自动水平伸缩、数据强一致性、跨数据中心高可用和云原生等重要特性。作为一个基础组件，TiKV 可作为构建其它系统的基石。目前，TiKV 已用于支持分布式 HTAP 数据库—— TiDB 中，负责存储数据，并已被多个行业的领先企业应用在实际生产环境。2019 年 5 月，CNCF 的 TOC（技术监督委员会）投票决定接受 TiKV 晋级为孵化项目。\n>\n>源码地址：https://github.com/tikv/tikv\n>\n>更多信息：https://tikv.org","date":"2019-11-28","author":"PingCAP","fillInMethod":"writeDirectly","customUrl":"tikv-maintainer-sunxiaoguang","file":null,"relatedBlogs":[]},{"id":"Blogs_28","title":"十分钟成为 Contributor 系列 | 为 Cascades Planner 添加优化规则","tags":["TiDB","社区","Contributor","优化器"],"category":{"name":"社区动态"},"summary":"我们将这个系列再向着数据库的核心前进一步，挑战一下「为 TiDB 的优化器增加优化规则」，带大家初步体验一下可以对查询的执行时间产生数量级影响的优化器的魅力。","body":"到今天为止，“成为 Contributor 系列”已经推出了 “[支持 AST 还原为 SQL](https://pingcap.com/blog-cn/support-ast-restore-to-sql-text/)”，“[为 TiKV 添加 built-in 函数](https://pingcap.com/blog-cn/30mins-become-contributor-of-tikv/)”，“[向量化表达式](https://pingcap.com/blog-cn/10mins-become-contributor-of-tidb-20190916/)”等一列活动。**这一次借着 TiDB 优化器重构的契机，我们将这个系列再向着数据库的核心前进一步，挑战一下「为 TiDB 的优化器增加优化规则」，带大家初步体验一下可以对查询的执行时间产生数量级影响的优化器的魅力。**\n\n众所周知优化器是数据库的核心组件，需要在合理的时间内寻找到一个合理的执行计划，确保查询可以稳定快速地返回正确的结果。最初的优化器只有一些启发式的优化规则，随着数据量和业务的变化，业界设计出了 System R 优化器框架来处理越来越多的复杂 SQL 查询。它将查询优化分为逻辑优化和物理优化两个阶段，逻辑优化根据规则对执行计划做等价变形，物理优化则根据统计信息和代价计算将逻辑执行计划转化为能更快执行的物理计划。目前 TiDB 优化器采用的也是该优化器模型。\n\n虽然 System R 优化器框架大大提升了数据库处理复杂 SQL 的能力，但也存在一定缺陷，比如：\n\n1. 扩展性不好。每次添加优化规则都需要考虑新的规则和老的规则之间的关系，需要对优化器非常了解的同学才能准确判断出新的优化规则应该处在什么位置比较好。另外每个优化规则都需要完整的遍历整个逻辑执行计划，添加优化规则的心智负担和知识门槛非常高。\n\n2. 搜索空间有限。搜索空间一方面因为优化规则难以添加导致比较狭小，另一方面，逻辑优化要求该优化规则一定在各个场景下都有收益才行，但在数据库面临的各种场景中，总有一些优化规则在某种数据分布下有收益，在另一种数据分布下没有收益，需要根据数据的分布估算代价来判断是否启用这些优化规则，因为这个原因，进一步导致一些优化规则不能添加到这个搜索框架中，或者添加后需要人工的通过开关来开启或关闭该优化规则。\n\n为了解决上面的问题，更方便地添加优化规则，扩展优化器搜索空间，寻找更优的执行计划，我们基于 Cascades 优化器模型重新写了一个新的优化器，名字就叫 Cascades Planner。在这个优化器框架下，添加优化规则变得异常简单：\n\n1. 不用考虑优化规则之间的顺序关系，规则和规则之间完全解耦。\n\n2. 只针对特定的模式添加优化规则，不再需要遍历整个逻辑执行计划，不用熟知所有逻辑算子的功能，极大的降低了优化器的开发门槛。\n\n在这篇文章中，我们主要聚焦在一条优化规则是如何工作以及如何给新优化器添加规则上，先让大家对这个优化器有一个直观的感受——“优化器没什么难的，不过如此”。下一篇文章，我们将更加详细的介绍 TiDB Cascades Planner 的原理和框架，供感兴趣的同学深入研究，如果大家等不及的话，可以先阅读下面的参考文献，提前了解一下 Cascades 优化器模型：\n\n1.  [The Cascades Framework for Query Optimization](https://15721.courses.cs.cmu.edu/spring2018/papers/15-optimizer1/graefe-ieee1995.pdf)\n\n2.  [Orca: A Modular Query Optimizer Architecture for Big Data](https://15721.courses.cs.cmu.edu/spring2016/papers/p337-soliman.pdf)\n\n3.  [CMU SCS 15-721 (Spring 2019) : Optimizer Implementation (Part II)](https://15721.courses.cs.cmu.edu/spring2019/slides/23-optimizer2.pdf)\n\n## Cascades 优化器简介\n\nCascades 优化器是 Goetz Graefe 在 [volcano optimizer generator](https://cs.uwaterloo.ca/~david/cs848/volcano.pdf) 的基础上优化调整之后诞生的一个搜索框架。这个框架有如下一些概念：\n\n* Expression：原论文中，Expression 用来指代包括 Plan 节点（也就是大家常说的的 SQL 算子）以及各种函数表达式（例如 MySQL 支持的 200 多个内置函数）在内的所有表达式。在 TiDB 现有框架实现中，只将 Plan 节点视作 Expression。Expression 大多会包含子节点，但每个子节点并不是一个 Expression ，而是一组等价的 Expression 集合，也就是接下来要介绍的 Group。\n\n* Group：表示等价 Expression 的集合，即同一个 Group 中的 Expression 在逻辑上等价。Expression 的每个子节点都是以一个 Group 表示的。在下文图例中，Group `G0` 中包含谓词下推前后的两个等价 Expression。\n\n* Transformation Rule：是作用于  Expression 和 Group 上的等价变化规则，用来扩大优化器搜索空间，也是本次要重点介绍的模块。下图 Group `G0` 中的第二组 `Expression` 便是第一组 `Expression` 经过了一个谓词条件（Filter）下推过连接（Join）的 Transformation Rule 之后新产生的 `Expression`。\n\n* Pattern：描述一个执行计划的片段，注意这个 “片段” 不是 “子树”。这个片段可以是执行计划算子树中任意一段。每一个 Transformation Rule 都拥有自己的 Pattern，表示该 Rule 只作用于满足这个 Pattern 的 Expression。\n\n* Implementation Rule：将一个逻辑算子转换成物理算子的规则。如一个 Join 可以被转换成 HashJoin、MergeJoin、IndexNestedLoopJoin 等。每一个转换都由一个对应的 Implementation Rule 完成。\n\n以查询 `select * from t1 join t2 on t1.a = t2.a where t1.b > 1` 为例，在经过 Cascades 优化器的谓词下推这一 Transformation Rule 后，搜索空间中的 Group 和 Expression 会是如下：\n\n![1-Group-and-Expression](https://img1.www.pingcap.com/prod/1_Group_and_Expression_e1f873432f.png)\n\n目前 TiDB 中 Cascades 优化器的搜索过程大致如下：\n\n1.  首先将抽象语法树（AST）转换为初始的逻辑执行计划，也就是由 LogicalPlan 所表示的算子树。\n\n2.  Cascades Planner 将这棵初始的 LogicalPlan 树等价地拆分到 `Group` 和 `GroupExpr` (Expression 在代码中对应的具体数据结构) 中，这样我们便得到了 Cascades Planner 优化器的初始输入。\n\n3.  Cascades Planner 将搜索的过程分为了两个阶段，第一阶段是 Exploration ，该阶段不停地遍历整个 Group ，应用所有可行的 Transformation Rule，产生新的 Group 和 GroupExpr ，不停迭代直到没有新的 GroupExpr 诞生为止。\n\n4.  在第二个阶段 Implementation 中，Cascades Planner 通过对 GroupExpr 应用对应的 Implementation Rule，为每一个 Group 搜索满足要求的最佳（Cost 最低）物理执行计划。\n\n5.  第二阶段结束后，Cascades Planner 将生成一个最终的物理执行计划，优化过程到此结束，物理执行计划交给 TiDB 执行引擎模块继续处理。\n\n## 一条优化规则如何工作\n\n目前所有的 Transformation Rule 的实现代码都放在 `planner/cascades/transformation_rules.go` 文件中。我们以 `PushSelDownProjection` 为例，来简单介绍一条 Transformation Rule 的工作流程。\n\nTransformation Rule 是一个 interface，该接口的定义如下（省去注释部分）：\n\n```\ntype Transformation interface {\n\tGetPattern() *memo.Pattern\n\tMatch(expr *memo.ExprIter) bool\n\tOnTransform(old *memo.ExprIter) (newExprs []*memo.GroupExpr, eraseOld bool, eraseAll bool, err error)\n}\n```\n\n在 Cascades 中，每个 rule 都会匹配一个局部的 Expression 子树，这里的 `GetPattern()` 就是返回这个 rule 所要匹配的 Pattern。Pattern 的具体结构如下（省去注释部分）：\n\n```\ntype Pattern struct {\n\tOperand\n\tEngineTypeSet\n\tChildren []*Pattern\n}\n```\n\n这里需要提一下的是 `EngineTypeSet` 这个参数，因为有的算子比如 Selection ，既可以在 TiDB 执行，也可以在 TiKV 或者 TiFlash（一个列存引擎，目前尚未开源）Coprocessor 上执行。为了处理只在特定执行引擎上生效的规则，我们引入了这个参数。\n\nPattern 的构造可以借助 `BuildPattern()` 以及 `NewPattern()` 来完成。对于 `PushSelDownProjection` 这个规则来说，它起作用的执行计划 Pattern 是 `Projection -> Selection`。\n\n```\nfunc (r *PushSelDownProjection) GetPattern() *memo.Pattern {\n\treturn memo.BuildPattern(\n\t\tmemo.OperandSelection,\n\t\tmemo.EngineTiDBOnly,\n\t\tmemo.NewPattern(memo.OperandProjection, memo.EngineTiDBOnly),\n\t)\n}\n```\n\n`Match()` 函数是在命中 Pattern 后再做的一些更具体的判断，因为 Pattern 只包含了算子类型和算子树的结构信息。这时比如有一个 Rule 只对 inner join 生效，Pattern 只能判断到算子是 Join，要进一步判断它是否是 inner join 就需要依靠 `Match()` 函数了。对于大部分简单的 Transformation Rule，所以 `Match()` 函数只需要简单地返回 `true` 就行了。\n\n`OnTransform()` 函数是规则的主要逻辑所在，在函数内部我们会创造新的 Expression 并返回合适的 `eraseOld` 以及 `eraseAll` 的值。举例来说，谓词下推会让计算尽可能提前，减少后续计算量，因此新生成地 Expression 一定是更好的选择，这时 `eraseOld` 就可以返回 `true `。类似地，当一个 rule 返回的 Expression 一定比其他所有选择都更好时，比如某一个优化规则发现 `a > 1 and a < 1` 恒为假后，判断查询一定不会有结果产生所以生成了 `TableDual` 的新 Expression ，这时就可以让 `eraseAll` 返回 `true` 让优化器将同 Group 内的其他 Expression 全部清空。\n\n`PushSelDownProjection` 的 `OnTransform()` 的行为如下图所示，简单来说：\n\n![2-OnTransform](https://img1.www.pingcap.com/prod/2_On_Transform_3a13f0f300.png)\n\n1. 在初始时只有 `G0` 和 `G1` 两个相关的 Group。\n\n2. 这个优化规则会将 `Selection` 推到 `Projection` 下面去，产生新的 Group `G2`，同时在 `G0` 中新增了 `Projection->G2` 的 `GroupExpr`。\n\n\n## 如何添加一个 Transformation Rule\n\n添加一个 Transformation Rule 简单来说就是编写一个新的结构体，实现 `Transformation` 这个 interface 的三个接口。Cascades 架构的优势就是它做了足够的抽象，让添加 Rule 的工作不需要考虑太多繁杂的事情。如果你在添加 Rule 时觉得有些地方写起来不是那么顺手，可以立刻停下手中的键盘来 [#sig-planner](https://tidbcommunity.slack.com/messages/sig-planner) 中和我们做一些讨论。\n\n当然这里还是要列出一些注意事项方便大家在添加 Transformation Rule 时不走歪路：\n\n*   `OnTransform()` 的函数头以及函数过程中添加充足的注释，说明自己的 Rule 做了一个什么样的变换，方便他人在读到这个 Rule 的代码时，能快速明白这个 Rule 做了哪些工作。\n\n*   `OnTransform()` 函数中不要对原有的 Expression 做任何修改，因为原有 Expression 可能之后会继续触发其他的行为，如果做了修改，那么在下一次触发规则时，就可能产生一些意想不到的化学反应。\n\n*   要在 `defaultTransformationRuleMap` 中注册这个 Rule，这个 Map 是 TiDB 目前默认的 `RuleSet`。使用 `RuleSet` 的好处很多，比如针对 TP 和 AP 查询使用不同的 Rule 集合，使得优化器在处理 TP 查询时能快速做出不差的执行计划，在处理 AP 查询时多应用一些优化规则做出执行时间更短的执行计划等。\n\n*   单元测试必不可少。目前，Transformation Rule 的测试在 `transformation_rules_test.go` 中。测试函数的编写可以参考文件下的其他函数，主要是以跑一个完整的 SQL 进行测试。为了减轻修改测试输出的工作量，我们将测试输入输出单独记录在文件中，并可以通过命令行快捷更新输出。在添加了测试函数后，需要修改 testdata 目录下的 `transformation_rules_suite_in.json` 文件添加测试的输入,然后用 `go test github.com/pingcap/tidb/planner/cascades --record` 即可生成对应的 `xxx_out.json` 文件。记得要检查测试的输出是否符合预期，确保测试结果是自己想要的等价变换。\n\n*   目前 Cascades 优化器仍在早期阶段，偶尔会有一些框架性的改动可能会制造一些需要解决的代码冲突，还请大家理解。\n\n## 如何成为 Contributor\n\n为了方便和社区讨论 Planner 相关事情，我们在 [TiDB Community Slack](https://pingcap.com/tidbslack/) 中创建了[#sig-planner](https://tidbcommunity.slack.com/messages/sig-planner) 供大家交流讨论，之后还将成立优化器的专项兴趣小组，不设门槛，欢迎感兴趣的同学加入。大家在添加规则时遇到一些问题时，可以毫不犹豫的来 channel 里和我们吐槽～\n\n**参与流程：**\n\n1.  在 [Cascades Tracking Issue](https://github.com/pingcap/tidb/issues/13709) 中 `porting the existing rules in the old planner` 选择感兴趣的函数并告诉大家你会完成它。\n\n2.  添加一个 rule 并为其增加单元测试。\n\n3.  运行 `make dev`，保证所有 test 都能通过。\n\n4.  发起 Pull Request 并完成 merge 到主分支。\n\n如果你有任何疑问，也欢迎到 [#sig-planner](https://tidbcommunity.slack.com/messages/sig-planner) 中提问和讨论。  \n> 点击查看更多 [成为 Contributor 系列文章](https://pingcap.com/zh/blog/?tag=Contributor)","date":"2019-11-26","author":"崔一丁","fillInMethod":"writeDirectly","customUrl":"10mins-become-contributor-20191126","file":null,"relatedBlogs":[]},{"id":"Blogs_273","title":"Unified Thread Pool | TiDB Hackathon 2019 优秀项目介绍","tags":["TiKV","社区","Hackathon"],"category":{"name":"社区动态"},"summary":"Unified Thread Pool 项目实现了在 TiKV 中使用一个统一的自适应线程池处理读请求，能够显著提升性能，并可预测性地限制大查询对小请求的干扰，最终在 TiDB Hackathon 2019 中斩获一等奖。","body":">本文由逊馁队的成员夏锐航同学主笔，介绍 Unified Thread Pool 项目的设计与实现过程。该项目实现了在 TiKV 中使用一个统一的自适应线程池处理读请求，能够显著提升性能，并可预测性地限制大查询对小请求的干扰，最终在 [TiDB Hackathon 2019](https://mp.weixin.qq.com/s?__biz=MzI3NDIxNTQyOQ==&mid=2247490046&idx=1&sn=962bb8aa4619c3815fcc561ed96331d7&chksm=eb163e94dc61b7826b7e73a057f4c9823261c1a79005104dd41dbd6ef4276c01bd6e41a69d14&scene=21&token=1896003006&lang=zh_CN#wechat_redirect) 中斩获一等奖。\n\n距离 TiDB Hackathon 落幕已经过去了半个多月，回忆这次比赛、获奖的经历，依然让我感到非常兴奋。我目前是华南理工大学大三的学生，我和正在 PingCAP 实习的学长奕霖一起组队参加了这次 TiDB Hackathon，比赛的主题为 “Improve”，即提升 TiDB 及相关项目的性能、易用性等。我们项目设计的切入点是： \n\n* TiKV 现有的线程池在大小查询混合场景下的表现不太优秀。\n\n* 需要针对不同的环境、场景配置线程池数量，使用和学习成本较高。\n\n于是我和奕霖尝试为 TiKV 重新实现一个线程池来解决这个问题，以达到 Improve 整体表现的效果。除了优化读请求的线程池外，我们计划将这个线程池来代替 TiKV 中其他线程池，最后就产生了我们本次的参赛作品 Unified Thread Pool。\n\n## 项目设计\n\n在 TiKV 现行的线程池方案中有 Coprocessor、Storage 和 Scheduler 三套线程池。这些线程池原本是设计来分隔不同的任务，减少它们之间的相互影响。这种方式简单粗暴，缺点也很明显，如：\n\n* 由于多个线程池共存，每个线程池都被限制至无法使用系统的全部资源。\n\n* 每套任务中又对应二至三个不同优先级的线程池，但是从实际效果来讲这个隔离也没能很好的发挥用处。\n\n* 在目前的 TiKV 中需要对每个线程池单独配置，如 [Scheduler](https://pingcap.com/docs-cn/v3.0/reference/configuration/tikv-server/configuration-file/#scheduler-worker-pool-size)、[Storage](https://pingcap.com/docs-cn/v3.0/reference/configuration/tikv-server/configuration-file/#readpoolstorage)、[Coprocessor](https://pingcap.com/docs-cn/v3.0/reference/configuration/tikv-server/configuration-file/#readpoolcoprocessor)。\n\n我们的 Unified Thread Pool 是一个在用户态模拟多级反馈队列调度的线程池，能较好的解决上述现行线程池方案的几个缺点。两者具体的对比如下表所示：\n\n| 现行线程池方案 | 我们的改进 |\n|:--------|:--------| \n| 多个线程池共存，每个线程池都不能分配所有的资源 | 一个统一的线程池，可以分配尽量多的资源|\n| 通过分配到不同的线程池来实现优先级，但效果不佳 | 内部实现按时间的调度 |\n| 大请求对小请求的影响不可控 | 可预测的大请求对系统的影响 |\n\n<div class=\"caption-center\">表 1 与现行线程池的对比</div>\n\nUnified Thread Pool 的调度方案参考自多级反馈队列算法，在 Unified Thread Pool 中一共有三个队列，worker 每次以不同的数量从不同的队列里面拿任务执行来表示优先级。不同于 OS 场景下的调度是以每个任务为单位，在这里一个 TiDB query 可能因为跨越多个 Region 而产生多个 TiKV task，如图 1 所示：\n\n![图 1 TiDB query 与 TiKV task 的关系](https://img1.www.pingcap.com/prod/1_tidb_query_tikv_task_9ca6e6f419.png)\n\n<div class=\"caption-center\">图 1 TiDB query 与 TiKV task 的关系</div>\n\n因此在这里我们需要以 TiDB 的 query 为单位进行调度。为了实现这一点我们让 TiDB 在发送 query 的时候带上一个 token 来作为标识，在线程池内我们也以 token（query）为整体来调整优先级。\n\n另一点很重要的改动是，现在 TiKV 中可能会出现一些大的 Coprocessor 请求，这些请求按 batch 执行，一个请求可能包含数百个 batches，执行一次就需要秒级的时间，使得对它们的调度无法进行。关于 Coprocessor 向量化执行的内容 PingCAP 后续也会有相关文章进行介绍。因此我们使用 Rust 最新的 async/await 协程机制，在 Coprocessor batches 之间手动埋点移交执行权，如下图所示，一个原本需要约一秒钟，包含约 500 个 batch 的任务在现在将会变为许多个时间约为一毫秒的小任务，在每个小任务之间会主动移交执行权。\n\n![图 2 将请求分成多次执行](https://img1.www.pingcap.com/prod/2_c2798f4a16.png)\n\n<div class=\"caption-center\">图 2 将请求分成多次执行</div>\n\n至此，Unified Thread Pool 已经基本能够通过动态调节队列的参数来实现资源对大小任务的分配，并且需要设置的参数非常简单，仅有一个表示当出现大小任务混杂的情形时小任务应占的计算资源的百分数。通过测试我们看到这个的分配的效果比较精确，如下图所示。\n\n![图 3 Configurable](https://img1.www.pingcap.com/prod/3_configurable_ff1eb63ea1.png)\n\n<div class=\"caption-center\">图 3 Configurable</div>\n\n## 比赛过程\n\n### Hacking Time\n\n在 10 月 26 日上午拿到 UCloud 提供的机器（8C16G）后，我们开始部署 TiDB 集群便于测试。第一次部署方案是 3TiDB + 3TiKV，但是当集群运行起来之后我们发现当请求压来时瓶颈似乎在 TiDB 上，于是我们将 TiKV 集群 down 掉一台，情况虽然有所好转但还是无法将 TiKV 跑到满负荷。一番挣扎无果后我们将整个集群铲掉重新部署，第二次按照 4TiDB + 1TiKV + 1Tester 部署完之后终于让瓶颈出现在 TiKV 上。\n\n详细的测试方案是使用 Tester 机器向四台 TiDB 发送请求然后检测延时和 QPS，sysbench 测试数据 32 张表，每张 10,000,000 条数据，总计容量约 80G。我们模拟了大小两种规格的请求，小请求是使用 sysbench 的 `point_selec t` 和 `read_only`，大请求则是使用四个 clients 不断地 `SELECT COUNT(*) FROM ..` 来扫表。下图是我们在上述测试环境中对 Unified Thread Pool 与 TiKV master 版本所做的对比，可以看到在单纯的小请求情况下吞吐量提高了 20%~50%。\n\n![图 4 fully utilize](https://img1.www.pingcap.com/prod/4_fully_utilize_3487511e6f.png)\n\n<div class=\"caption-center\">图 4 fully utilize</div>\n\n### 睁眼吃喝闭眼睡\n\n众所周知 Hackathon 不变的主题就是吃吃喝喝，这一次也一样。PingCAP 为选手们提供了丰富的三餐，配上广州 office 的装潢简直像在度假。午餐有超多口味可以选，到了晚上一会议桌的虾蟹的确是太有视觉冲击力。除了正餐之外，还有不限量供应的零食咖啡快乐水，实在是太幸福了。\n\n在比赛开始之前就有一件非常好奇的事情，就是据说现场晚上有三张床垫，不知道会出现怎样难上加难的场景。结果真的到了犯困的时候才发现原来其他人是根本不睡的……\n\n晚上两点左右感觉刚跑完的测试效果还行，就找了间放了床的小会议室准备做梦。可是充气床垫的气已经漏完了，在茶水间里面翻到充气装置之后打算给它重启，但是插头插上之后气泵的声音在深夜里面真是大得不行，不知道之前工作人员是怎样悄无声息地把三个床垫给充起来的。为了防止噪音扰民，我们把床垫卷到大楼下一层（洗手间旁边）的小房间里面充气，期间还引来了两位像是保安的叔叔来看看发生了什么。接下来和奕霖两个人扛着两米的床垫走过会议室走过茶水间走过工位，走进小卧室的那一段路，实在是令人印象非常深刻。\n\n这栋楼的空调效果真是非常强劲，虽然不是第一次在贵司被冷到，但是这一回来的时候依旧没有带外套。即使睡觉之前已经把空调关掉了，还是和带了外套但没拿出来的奕霖在床上缩成了两团。\n\n## 写在 Hackathon 之后\n\n比赛最后 Demo Time 的时候看别人的项目都好优秀，看得有点想提前跑路了，还好不是我上去做 presentation，能夺魁事实上挺让我感到意外的，现在 Hackathon 虽然已经结束了，但还想继续完善这个作品。现在它虽然能提升最大吞吐量，但是在延时方面的表现还能更进一步。在比赛时我们的线程池是基于比较简单的 juliex 来设计的，后续计划参考一些比如 tokio 之类的成熟的线程池来进行优化，希望能够将它完善合进 master。大家可以在 [TiDB 性能挑战赛](https://pingcap.com/community-cn/tidb-performance-challenge/) 中继续一起鼓捣这个项目，该项目对应的 [链接](https://github.com/tikv/tikv/issues/5765)。\n\n最后感谢奕霖老师这么强还愿意带我玩，感谢 PingCAP 让我蹭吃蹭喝的辛苦付出 :D \n\n>附：[逊馁队 Demo Show 视频（0:00 - 10:35）](https://v.qq.com/x/page/s30152xwbyj.html)","date":"2019-11-14","author":"夏锐航","fillInMethod":"writeDirectly","customUrl":"unified-thread-pool","file":null,"relatedBlogs":[]},{"id":"Blogs_283","title":"TiDB-Wasm 原理与实现 | TiDB Hackathon 2019 优秀项目介绍","tags":["Hackathon","社区","WebAssembly"],"category":{"name":"社区动态"},"summary":"TiDB-Wasm 项目实现了将 TiDB 编译成 Wasm 运行在浏览器里，让用户无需安装就可以使用 TiDB，最终获得了 TiDB Hackathon 2019 的二等奖。","body":">上周我们推送了《[让数据库运行在浏览器里？TiDB + WebAssembly 告诉你答案](https://pingcap.com/blog-cn/tidb-in-the-browser-running-a-golang-database-on-wasm/)》，向大家展示了 TiDB-Wasm 的魅力：TiDB-Wasm 项目是 TiDB Hackathon 2019 中诞生的二等奖项目，实现了将 TiDB 编译成 Wasm 运行在浏览器里，让用户无需安装就可以使用 TiDB。\n>\n>本文由 Ti-Cool 队成员主笔，为大家详细介绍 TiDB-Wasm 设计与实现细节。\n\n\n\n10 月 27 日，为期两天的 Hackathon 落下帷幕，我们用一枚二等奖为此次上海之行画上了圆满的句号，不枉我们风尘仆仆跑去异地参赛（强烈期待明年杭州能作为赛场，主办方也该鼓励鼓励杭州当地的小伙伴呀 :D ）。\n\n我们几个 PingCAP 的小伙伴找到了 Tony 同学一起组队，组队之后找了一个周末进行了“秘密会晤”——Hackathon kick off。想了 N 个 idea，包括使用 unikernel 技术将 TiDB 直接跑在裸机上，或者将网络协议栈做到用户态以提升 TiDB 集群性能，亦或是使用异步 io 技术提升 TiKV 的读写能力，这些都被一一否决，原因是这些 idea 不是和 Tony 的工作内容相关，就是和我们 PingCAP 小伙伴的日常工作相关，做这些相当于我们在 Hackathon 加了两天班，这一点都不酷。本着「与工作无关」的标准，我们想了一个 idea：把 TiDB 编译成 Wasm 运行在浏览器里，让用户无需安装就可以使用 TiDB。我们一致认为这很酷，于是给队伍命名为 Ti-Cool（太酷了）。\n\n## WebAssembly 简介\n\n这里插入一些 WebAssembly 的背景知识，让大家对这个技术有个大致的了解。\n\nWebAssembly 的 [官方介绍](https://webassembly.org/) 是这样的：WebAssembly（缩写为 Wasm）是一种为基于堆栈的虚拟机设计的指令格式。它被设计为 C/C++/Rust 等高级编程语言的可移植目标，可在 web 上部署客户端和服务端应用程序。\n\n从上面一段话我们可以得出几个信息：\n\n1.  Wasm 是一种可执行的指令格式。\n2.  C/C++/Rust 等高级语言写的程序可以编译成 Wasm。\n3.  Wasm 可以在 web（浏览器）环境中运行。\n\n### 可执行指令格式\n\n看到上面的三个信息我们可能又有疑问：什么是指令格式？\n\n我们常见的 [ELF 文件](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format) 就是 Unix 系统上最常用的二进制指令格式，它被 loader 解析识别，加载进内存执行。同理，Wasm 也是被某种实现了 Wasm 的 runtime 识别，加载进内存执行，目前常见的实现了 Wasm runtime 的工具有各种主流浏览器，nodejs，以及一个专门为 Wasm 设计的通用实现：Wasmer，甚至还有人给 Linux 内核提 feature 将 Wasm runtime 集成在内核中，这样用户写的程序可以很方便的跑在内核态。\n\n各种主流浏览器对 WebAssembly 的支持程度：\n\n![图 1 主流浏览器对 WebAssembly 的支持程度](https://img1.www.pingcap.com/prod/1_Web_Assembly_bb82022048.png)\n\n<div class=\"caption-center\">图 1 主流浏览器对 WebAssembly 的支持程度</div> \n\n### 从高级语言到 Wasm \n\n有了上面的背景就不难理解高级语言是如何编译成 Wasm 的，看一下高级语言的编译流程：\n\n![图 2 高级语言编译流程](https://img1.www.pingcap.com/prod/2_5efe7e301a.png)\n\n<div class=\"caption-center\">图 2 高级语言编译流程</div> \n\n我们知道高级编程语言的特性之一就是可移植性，例如 C/C++ 既可以编译成 x86 机器可运行的格式，也可以编译到 ARM 上面跑，而我们的 Wasm 运行时和 ARM，x86_32 其实是同类东西，可以认为它是一台虚拟的机器，支持执行某种字节码，这一点其实和 Java 非常像，实际上 C/C++ 也可以编译到 JVM 上运行（参考：[compiling-c-for-the-jvm](https://stackoverflow.com/questions/4221605/compiling-c-for-the-jvm)）。\n\n### 各种 runtime 以及 WASI\n\n再啰嗦一下各种环境中运行 Wasm 的事，上面说了 Wasm 是设计为可以在 web 中运行的程序，其实 Wasm 最初设计是为了弥补 js 执行效率的问题，但是发展到后面发现，这玩意儿当虚拟机来移植各种程序也是很赞的，于是有了 nodejs 环境，Wasmer 环境，甚至还有内核环境。\n\n这么多环境就有一个问题了：各个环境支持的接口不一致。比如 nodejs 支持读写文件，但浏览器不支持，这挑战了 Wasm 的可移植性，于是 WASI (WebAssembly System Interface) 应运而生，它定义了一套底层接口规范，只要编译器和 Wasm 运行环境都支持这套规范，那么编译器生成的 Wasm 就可以在各种环境中无缝移植。如果用现有的概念来类比，Wasm runtime 相当于一台虚拟的机器，Wasm 就是这台机器的可执行程序，而 WASI 是运行在这台机器上的系统，它为 Wasm 提供底层接口（如文件操作，socket 等）。\n\nExample or  Hello World？\n\n程序员对 Hello World 有天生的好感，为了更好的说明 Wasm 和 WASI 是啥，我们这里用一个 Wasm 的 Hello World 来介绍（例程来源：[chai2010-golang-wasm.slide#27](https://talks.godoc.org/github.com/chai2010/awesome-go-zh/chai2010/chai2010-golang-wasm.slide#27)）：\n\n```lisp\n(module\n    ;; type iov struct { iov_base, iov_len int32 }\n    ;; func fd_write(id *iov, iovs_len int32, nwritten *int32) (written int32)\n    (import \"wasi_unstable\" \"fd_write\" (func $fd_write (param i32 i32 i32 i32) (result i32)))\n\n    (memory 1)(export \"memory\" (memory 0))\n\n    ;; The first 8 bytes are reserved for the iov array, starting with address 8\n    (data (i32.const 8) \"hello world\\n\")\n\n    ;; _start is similar to main function, will be executed automatically\n    (func $main (export \"_start\")\n        (i32.store (i32.const 0) (i32.const 8))  ;; iov.iov_base - The string address is 8\n        (i32.store (i32.const 4) (i32.const 12)) ;; iov.iov_len  - String length\n\n        (call $fd_write\n            (i32.const 1)  ;; 1 is stdout\n            (i32.const 0)  ;; *iovs - The first 8 bytes are reserved for the iov array\n            (i32.const 1)  ;; len(iovs) - Only 1 string\n            (i32.const 20) ;; nwritten - Pointer, inside is the length of the data to be written\n        )\n        drop ;; Ignore return value\n    )\n)\n```\n\n\n具体指令的解释可以参考 [这里](https://pengowray.github.io/wasm-ops/html/wasm-opcodes.html)。\n\n这里的 test.wat 是 Wasm 的文本表示，wat 之于 Wasm 的关系类似于汇编和 ELF 的关系。\n\n然后我们把 wat 编译为 Wasm 并且使用 Wasmer（一个通用的 Wasm 运行时实现）运行：\n\n![图 3 Hello World](https://img1.www.pingcap.com/prod/3_hello_world_64a0063205.png)\n\n<div class=\"caption-center\">图 3 Hello World</div> \n\n## 改造工作\n\n恐惧来自未知，有了背景知识动起手来才无所畏惧，现在可以开启 TiDB 的浏览器之旅。\n\n### 浏览器安全限制\n\n我们知道，浏览器本质是一个沙盒，是不会让内部的程序做一些危险的事情的，比如监听端口，读写文件。而 TiDB 的使用场景实际是用户启动一个客户端通过 MySQL 协议连接到 TiDB，这要求 TiDB 必须监听某个端口。\n\n**考虑片刻之后，我们认为即便克服了浏览器沙盒这个障碍，真让用户用 MySQL 客户端去连浏览器也并不是一个优雅的事情，我们希望的是用户在页面上可以有一个开箱即用的 MySQL 终端，它已经连接好了 TiDB。**\n\n于是我们第一件事是给 TiDB 集成一个终端，让它启动后直接弹出这个终端接受用户输入 SQL。所以我们需要在 TiDB 的代码中找到一个工具，它的输入是一串 SQL，输出是 SQL 的执行结果，写一个这样的东西对于我们几个没接触过 TiDB 代码的人来说还是有些难度，于是我们想到了一个捷径：TiDB 的测试代码中肯定会有输入 SQL 然后检查输出的测试。那么把这种测试搬过来改一改不就是我们想要的东西嘛？然后我们翻了翻 TiDB 的测试代码，发现了大量的这样的用法：\n\n```go\nresult = tk.MustQuery(\"select count(*) from t group by d order by c\")\nresult.Check(testkit.Rows(\"3\", \"2\", \"2\"))\n```\n\n所以我们只需要看看这个 `tk` 是个什么东西，借来用一下就行了。这是 `tk` 的主要函数：\n\n```go\n// Exec executes a sql statement.\nfunc (tk *TestKit) Exec(sql string, args ...interface{}) (sqlexec.RecordSet, error) {\n    var err error\n    if tk.Se == nil {\n        tk.Se, err = session.CreateSession4Test(tk.store)\n        tk.c.Assert(err, check.IsNil)\n        id := atomic.AddUint64(&connectionID, 1)\n        tk.Se.SetConnectionID(id)\n    }\n    ctx := context.Background()\n    if len(args) == 0 {\n        var rss []sqlexec.RecordSet\n        rss, err = tk.Se.Execute(ctx, sql)\n        if err == nil && len(rss) > 0 {\n            return rss[0], nil\n        }\n        return nil, errors.Trace(err)\n    }\n    stmtID, _, _, err := tk.Se.PrepareStmt(sql)\n    if err != nil {\n        return nil, errors.Trace(err)\n    }\n    params := make([]types.Datum, len(args))\n    for i := 0; i < len(params); i++ {\n        params[i] = types.NewDatum(args[i])\n    }\n    rs, err := tk.Se.ExecutePreparedStmt(ctx, stmtID, params)\n    if err != nil {\n        return nil, errors.Trace(err)\n    }\n    err = tk.Se.DropPreparedStmt(stmtID)\n    if err != nil {\n        return nil, errors.Trace(err)\n    }\n    return rs, nil\n}\n```\n\n\n剩下的事情就非常简单了，写一个 Read-Eval-Print-Loop (REPL)  读取用户输入，将输入交给上面的 Exec，再将 Exec 的输出格式化到标准输出，然后循环继续读取用户输入。\n\n### 编译问题\n\n**集成一个终端只是迈出了第一步，我们现在需要验证一个非常关键的问题：TiDB 能不能编译到 Wasm，虽然 TiDB 是 Golang 写的，但是中间引用的第三方库没准哪个写了平台相关的代码就没法直接编译了**。\n\n我们先按照 [Golang 官方文档](https://github.com/golang/go/wiki/WebAssembly#getting-started) 编译：\n\n![图 4 按照 Golang 官方文档编译（1/2）](https://img1.www.pingcap.com/prod/4_Golang_fd0d70cd50.png)\n\n<div class=\"caption-center\">图 4 按照 Golang 官方文档编译（1/2）</div> \n\n\n果然出师不利，查看 goleveldb 的代码发现，storage 包下面的代码针对不同平台有各自的实现，唯独没有 Wasm/js 的：\n\n![图 5 按照 Golang 官方文档编译（2/2）](https://img1.www.pingcap.com/prod/5_Golang_2_f3c8981b94.png)\n\n<div class=\"caption-center\">图 5 按照 Golang 官方文档编译（2/2）</div> \n\n所以在 Wasm/js 环境下编译找不到一些函数。所以这里的方案就是添加一个 `file_storage_js.go`，然后给这些函数一个 unimplemented 的实现：\n\n```go\npackage storage\n\nimport (\n\t\"os\"\n\t\"syscall\"\n)\n\nfunc newFileLock(path string, readOnly bool) (fl fileLock, err error) {\n\treturn nil, syscall.ENOTSUP\n}\n\nfunc setFileLock(f *os.File, readOnly, lock bool) error {\n\treturn syscall.ENOTSUP\n}\n\nfunc rename(oldpath, newpath string) error {\n\treturn syscall.ENOTSUP\n}\n\nfunc isErrInvalid(err error) bool {\n\treturn false\n}\n\nfunc syncDir(name string) error {\n\treturn syscall.ENOTSUP\n}\n```\n\n\n然后再次编译：\n\n![图 6 再次编译的结果](https://img1.www.pingcap.com/prod/6_c94bb771de.png)\n\n<div class=\"caption-center\">图 6 再次编译的结果</div> \n\nemm… 编译的时候没有函数可以说这个函数没有 Wasm/js 对应的版本，没有 body 是个什么情况？好在我们有代码可以看，到 `arith_decl.go` 所在的目录看一下就知道怎么回事了：\n\n![图 7 查看目录](https://img1.www.pingcap.com/prod/7_2f505b9d70.png)\n\n<div class=\"caption-center\">图 7 查看目录</div> \n\n然后 `arith_decl.go` 的内容是一些列的函数声明，但是具体的实现放到了上面的各个平台相关的汇编文件中了。\n\n看起来还是和刚刚一样的情况，我们只需要为 Wasm 实现一套这些函数就可以了。但这里有个问题是，这是一个代码不受我们控制的第三方库，并且 TiDB 不直接依赖这个库，而是依赖了一个叫 `mathutil` 的库，然后 `mathutil` 依赖这个 `bigfft`。悲催的是，这个 `mathutil` 的代码也不受我们控制，因此很直观的想到了两种方案：\n\n1.  给这两个库的作者提 PR，让他们支持 Wasm。\n\n2.  我们将这两个库 clone 过来改掉，然后把 TiDB 依赖改到我们 clone 过来的库上。\n\n方案一的问题很明显，整个周期较长，等作者接受 PR 了我们的 Hackathon 都凉凉了（而且还不一定会接受）；方案二的问题也不小，这会导致我们和上游脱钩。那么有没有第三种方案呢，即在编译 Wasm 的时候不依赖这两个库，在编译正常的二进制文件的时候又用这两个库？经过搜索发现，我们很多代码都用到了 `mathutil`，但是基本上只用了几个函数：`MinUint64`，`MaxUint64`，`MinInt32`，`MaxInt32` 等等，我们想到的方案是：\n\n1.  新建一个 `mathutil` 目录，在这个目录里建立 `mathutil_linux.go` 和 `mathutil_js.go`。\n\n2.  在 `mathutil_linux.go` 中 reexport 第三方包的几个函数。\n\n3.  在 `mathutil_js.go` 中自己实现这几个函数，不依赖第三方包。\n\n4.  将所有对第三方的依赖改到 `mathutil` 目录上。\n\n这样，`mathutil` 目录对外提供了原来 `mathutil` 包的函数，同时整个项目只有 `mathutil` 目录引入了这个不兼容 Wasm 的第三方包，并且只在 `mathutil_linux.go` 中引入（`mathutil_js.go` 是自己实现的），因此编译 Wasm 的时候就不会再用到 `mathutil` 这个包。\n\n再次编译，成功了！\n\n![图 8 编译成功](https://img1.www.pingcap.com/prod/8_605335a0db.png)\n\n<div class=\"caption-center\">图 8 编译成功</div> \n\n### 兼容性问题\n\n编译出 main.Wasm 按照 Golang 的 Wasm 文档跑一下，由于目前是直接通过 os.Stdin 读用户输入的 SQL，通过 os.Stdout 输出结果，所以理论上页面上会是空白的（我们还没有操作 dom），但是由于 TiDB 的日志会打向 os.Stdout，所以在浏览器的控制台上应该能看到 TiDB 正常启动的日志才对。然而很遗憾看到的是异常栈：\n\n![图 9 异常栈](https://img1.www.pingcap.com/prod/9_9bba775501.png)\n\n<div class=\"caption-center\">图 9 异常栈</div> \n\n可以看到这个错是运行时没实现 os.stat 操作，这是因为目前的 Golang 没有很好的支持 WASI，它仅在 `wasm_exec.js` 中 mock 了一个 `fs`:\n\n```js\nglobal.fs = {\n        writeSync(fd, buf) {\n                ...\n        },\n        write(fd, buf, offset, length, position, callback) {\n                ...\n        },\n        open(path, flags, mode, callback) {\n                ...\n        },\n        ...\n}\n```\n\n而且这个 mock 的 `fs` 并没有实现 `stat`, `lstat`, `unlink`, `mkdir` 之类的调用，那么解决方案就是我们在启动之前在全局的 `fs` 对象上 mock 一下这几个函数：\n\n```js\nfunction unimplemented(callback) {\n    const err = new Error(\"not implemented\");\n    err.code = \"ENOSYS\";\n    callback(err);\n}\nfunction unimplemented1(_1, callback) { unimplemented(callback); }\nfunction unimplemented2(_1, _2, callback) { unimplemented(callback); }\n\nfs.stat = unimplemented1;\nfs.lstat = unimplemented1;\nfs.unlink = unimplemented1;\nfs.rmdir = unimplemented1;\nfs.mkdir = unimplemented2;\ngo.run(result.instance);\n```\n\n然后再刷新页面，在控制台上出现了久违的日志：\n\n![图 10 日志信息](https://img1.www.pingcap.com/prod/10_b8695aed1c.png)\n\n<div class=\"caption-center\">图 10 日志信息</div> \n\n到目前为止就已经解决了 TiDB 编译到 Wasm 的所有技术问题，剩下的工作就是找一个合适的能运行在浏览器里的 SQL 终端替换掉前面写的终端，和 TiDB 对接上就能让用户在页面上输入 SQL 并运行起来了。\n\n### 用户接口\n\n通过上面的工作，我们现在有了一个 Exec 函数，它接受 SQL 字符串，输出 SQL 执行结果，并且它可以在浏览器里运行，我们还需要一个浏览器版本 SQL 终端和这个函数交互，两种方案：\n\n1.  使用 Golang 直接操作 dom 来实现这个终端。\n\n2.  在 Golang 中把 Exec 暴露到全局，然后找一个现成的 js 版本的终端和这个全局的 Exec 对接。\n\n对于前端小白的我们来说，第二种方式成本最低，我们很快找到了 jquery.console.js 这个库，它只需要传入一个 SQL 处理的 callback 即可运行，而我们的 Exec 简直就是为这个 callback 量身打造的。\n\n因此我们第一步工作就是把 Exec 挂到浏览器的 window 上（暴露到全局给 js 调用）：\n\n```go\njs.Global().Set(\"executeSQL\", js.FuncOf(func(this js.Value, args []js.Value) interface{} {\n    go func() {\n\t    // Simplified code\n\t    sql := args[0].String()\n\t    args[1].Invoke(k.Exec(sql))\n    }()\n    return nil\n}))\n```\n\n这样就能在浏览器的控制台运行 SQL 了：\n\n![图 11 在浏览器控制台运行 SQL](https://img1.www.pingcap.com/prod/11_SQL_7e8203a29a.png)\n\n<div class=\"caption-center\">图 11 在浏览器控制台运行 SQL</div> \n\n然后将用 jquery.console.js 搭建一个 SQL 终端，再将 executeSQL 作为 callback 传入，大功告成：\n\n![图 12 搭建 SQL 终端](https://img1.www.pingcap.com/prod/12_SQL_9634e8b8c0.png)\n\n<div class=\"caption-center\">图 12 搭建 SQL 终端</div> \n\n现在算是有一个能运行的版本了。\n\n### 本地文件访问\n\n还有一点点小麻烦要解决，那就是 TiDB 的 load stats 和 load data 功能。load data 语法和功能详解可以参考 [TiDB 官方文档](https://pingcap.com/docs-cn/v3.0/reference/sql/statements/load-data/)，其功能简单的说就是用户指定一个文件路径，然后客户端将这个文件内容传给 TiDB，TiDB 将其加载到指定的表里。我们的问题在于，浏览器中是不能读取用户电脑上的文件的，于是我们只好在用户执行这个语句的时候打开浏览器的文件上传窗口，让用户主动选择一个这样的文件传给 TiDB：\n\n```go\njs.Global().Get(\"upload\").Invoke(js.FuncOf(func(this js.Value, args []js.Value) interface{} {\n    go func() {\n        fileContent := args[0].String()\n        _, e := doSomething(fileContent)\n        c <- e\n    }()\n    return nil\n}), js.FuncOf(func(this js.Value, args []js.Value) interface{} {\n    go func() {\n        c <- errors.New(args[0].String())\n    }()\n    return nil\n}))\n```\n\nload stats 的实现也是同理。\n\n**此外，我们还使用同样的原理 “自作主张” 加入了一个新的指令：source，用户执行这个命令可以上传一个 SQL 文件，然后我们会执行这个文件里的语句。我们认为这个功能的主要使用场景是：用户初次接触 TiDB 时，想验证其对 MySQL 的兼容性，但是一条一条输入 SQL 效率太低了，于是可以将所有用户业务中用到的 SQL 组织到一个 SQL 文件中（使用脚本或其他自动化工具），然后在页面上执行 source 导入这个文件，验证结果。**\n\n以一个 test.sql 文件为例，展示下 source 命令的效果，test.sql 文件内容如下：\n\n```sql\nCREATE DATABASE IF NOT EXISTS samp_db;\n\nUSE samp_db;\n\nCREATE TABLE IF NOT EXISTS person (\n      number INT(11),\n      name VARCHAR(255),\n      birthday DATE\n);\n\nCREATE INDEX person_num ON person (number);\n\nINSERT INTO person VALUES(\"1\",\"tom\",\"20170912\");\n\nUPDATE person SET birthday='20171010' WHERE name='tom';\n```\n\nsource 命令执行之后弹出文件选择框：\n\n![图 13 source 命令执行（1/2）](https://img1.www.pingcap.com/prod/13_source_9d81cc17e2.png)\n\n<div class=\"caption-center\">图 13 source 命令执行（1/2）</div> \n\n选中 SQL 文件上传后自动执行，可以对数据库进行相应的修改：\n\n![图 14 source 命令执行（2/2）](https://img1.www.pingcap.com/prod/14_source_2_c4633a909f.png)\n\n<div class=\"caption-center\">图 14 source 命令执行（2/2）</div> \n\n## 总结与展望\n\n总的来说，这次 Hackathon 为了移植 TiDB 我们主要解决了几个问题：\n\n1.  浏览器中无法监听端口，我们给 TiDB 嵌入了一个 SQL 终端。\n\n2.  goleveldb 对 Wasm 的兼容问题。\n\n3.  bigfft 的 Wasm 兼容问题。\n\n4.  Golang 自身对 WASI 支持不完善导致的 fs 相关函数缺失。\n\n5.  TiDB 对本地文件加载转换为浏览器上传文件方式加载。\n\n6.  支持 source 命令批量执行 SQL。\n\n**目前而言我们已经将这个项目作为 TiDB Playground ([https://play.pingcap.com/](https://play.pingcap.com/)) 和 TiDB Tour ([https://tour.pingcap.com/](https://tour.pingcap.com/)) 开放给用户使用。由于它不需要用户安装配置就能让用户在阅读文档的同时进行尝试，很大程度上降低了用户学习使用 TiDB 的成本，社区有小伙伴已经基于这些自己做数据库教程了，譬如：[imiskolee/tidb-wasm-markdown](https://github.com/imiskolee/tidb-wasm-markdown)（[相关介绍文章](https://mp.weixin.qq.com/s/0Vo4apK4VdBfOs0-KyWXZA)）。**\n\n![图 15 TiDB Playground](https://img1.www.pingcap.com/prod/0_tidb_playground_322c451057.png)\n\n<div class=\"caption-center\">图 15 TiDB Playground</div> \n\n由于 Hackathon 时间比较紧张，其实很多想做的东西还没实现，比如：\n\n1.  使用 indexedDB 让数据持久化：需要针对 indexedDB 实现一套 Storage 的 interface。\n\n2.  使用 P2P 技术（如 webrtc）对其他浏览器提供服务：未来必定会有越来越多的应用迁移到 Wasm，而很多应用是需要数据库的，TiDB-Wasm 恰好可以扮演这样的角色。\n\n3.  给 TiDB 的 Wasm 二进制文件瘦身：目前编译出来的二进制文件有将近 80M，对浏览器不太友好，同时运行时占用内存也比较多。\n\n欢迎更多感兴趣的社区小伙伴们加入进来，一起在这个项目上愉快的玩耍（[github.com/pingcap/tidb/projects/27](https://github.com/pingcap/tidb/projects/27)），也可以通过 [info@pingcap.com](mailto:info@pingcap.com) 联系我们。","date":"2019-11-12","author":"Ti-Cool","fillInMethod":"writeDirectly","customUrl":"tidb-wasm-introduction","file":null,"relatedBlogs":[]},{"id":"Blogs_163","title":"如何玩转 TiDB 性能挑战赛？本文教你 30 分钟快速上手拿积分！","tags":["TiKV","社区","性能挑战赛"],"category":{"name":"社区动态"},"summary":"本文以 TiKV 性能挑战赛 Easy 级别任务“PCP：Migrate functions from TiDB”为例，教大家如何快速又正确地完成这个任务。","body":"上周我们正式宣布了 [TiDB 性能挑战赛](https://pingcap.com/community-cn/tidb-performance-challenge/)。在赛季内，通过向 TiDB、TiKV、PD 贡献代码完成指定类别任务的方式，你可以获得相应的积分，最终你可以使用积分兑换礼品或奖金。在性能挑战赛中，你首先需要完成几道 Easy 的题目，积累一定量积分后，才能开始挑战 Medium / Hard 难度的题目。\n\n活动发布后，大家向我们反馈 TiKV 任务的资料比较少，上手难度比较高。因此本文以 TiKV 性能挑战赛 Easy 级别任务 [PCP: Migrate functions from TiDB](https://github.com/tikv/tikv/issues/5751) 为例，教大家如何快速又正确地完成这个任务，从而玩转“TiDB 性能挑战赛”。这个任务中每项完成后均可以获得 50 分，是积累分数从而挑战更高难度任务的好机会。既能改进 TiKV 为性能提升添砖加瓦、又能参与比赛得到积分，还能成为 Contributor，感兴趣的小伙伴们一起来“打怪”吧！\n\n## 背景知识\n\nTiKV Coprocessor（协处理）模块为 TiDB 提供了在存储引擎侧直接进行部分 SQL 计算的功能，支持按表达式进行过滤、聚合等，这样不仅利用起了 TiKV 机器的 CPU 资源，还能显著减少网络传输及相应的 RPC 开销，显著提升性能。大家可以阅读 [《TiKV 源码解析系列文章（十四）Coprocessor 概览》](https://pingcap.com/blog-cn/tikv-source-code-reading-14/)一文进一步了解 Coprocessor 模块。\n\n表达式计算是 Coprocessor 非常重要的一个功能，例如用户输入了这样的 SQL：\n\n```sql\nSELECT * FROM t WHERE  sqrt(col_area) > 10;\n```\n\nTiKV Coprocessor 使用表达式 `sqrt(col_area) > 10` 对每一行进行求值，并根据结果对数据进行过滤，最后将过滤后的结果返回给 TiDB。为了能计算这个表达式，TiKV 必须实现与 TiDB 行为一致的 `Sqrt` 函数，当然 `>` 运算符也要提供对应的实现，这些统称为内置函数（built-in function）。\n\nTiDB 和 MySQL 有非常多的内置函数，但 TiKV 目前只实现了一部分，只有当用户输入的表达式完全被 TiKV 支持并已经进行充分测试时，对应的表达式才会被下推到 Coprocessor 执行，否则 TiDB 只能从 TiKV 捞完整数据上来，达不到加速目的。\n\n另外，TiKV 从 3.0 版本开始就包含两套 Coprocessor 执行框架，一套是老的框架，基于火山模型（推荐阅读 paper： [Volcano - An Extensible and Parallel Query Evaluation System](https://paperhub.s3.amazonaws.com/dace52a42c07f7f8348b08dc2b186061.pdf)）实现，另一套是 3.0 的新框架，基于向量化模型（推荐阅读 paper：[MonetDB/X100: Hyper-Pipelining Query Execution](http://cidrdb.org/cidr2005/papers/P19.pdf)）实现。火山模型中每个算子和函数都按行一个一个计算，向量化模型中则按列批量计算。由于在向量化模型中一个批次进行的处理操作是一样的，因此它可以规避条件分支，且能更好地利用流水线与缓存，从而具有更高的计算效率，差距可达 10 倍以上。\n\n既然两个模型中函数处理的数据单位是不一样的，它们自然也有不一样的函数签名及实现，因此还有一大批内置函数虽然在 TiKV 侧已经实现了，但只有火山模型的实现，而没有向量化模型的实现。这类函数虽然 TiDB 已下推计算，但 TiKV 会回退到使用火山模型而不是向量化模型，无法达成最优计算效率。\n\n综上，TiDB 内置函数在 TiKV 侧有几种实现状态：\n\n1.  完全没有实现，如 `FromDays` 函数。\n\n2.  已有火山模型的实现，没有向量化模型的实现，如 `BitLength` 函数。\n\n3.  火山模型和向量化都已实现，如 `LTReal` 函数。\n\n[PCP: Migrate functions from TiDB](https://github.com/tikv/tikv/issues/5751) 这个任务就是希望大家能帮助我们在 TiKV 侧实现更多 TiDB 所支持的内置函数，并支持向量化计算。这个 issue 中 Non-Vectorize 打钩意味着函数已有火山模型的实现，Vectorized 打钩意味着函数已有向量化模型的实现。因此你可以：\n\n*   选择一个完全没有实现的函数，如 `FromDays`，从 TiDB 侧迁移它的代码到 TiKV 并实现在火山模型（Non-Vectorize）上，提个 PR +50 积分，再迁移到向量化模型（Vectorize）上，从而再提个 PR +50 积分。\n\n*   或选择一个已有火山模型但没有向量化实现的函数，如 `BitLength` 函数，为它适配向量化模型（Vectorize）接口，提个 PR +50 积分。\n\n**实现一个完全没有在 TiKV 侧实现的内置函数一般来说具有更高难度，因此能获得更高回报！**\n\n## 如何从 TiDB 迁移内置函数在火山模型上实现\n\n这部分在 [《三十分钟成为 Contributor | 为 TiKV 添加 built-in 函数》](https://pingcap.com/blog-cn/30mins-become-contributor-of-tikv) 中有所介绍，大家可以照着这个教程来，这里就不再赘述。\n\n>注：由于 Coprocessor 框架实现的是 Fallback 机制，不允许函数只有向量化实现而没有火山模型实现。因此，若一个内置函数完全没有在 TiKV 侧实现，请先将它在火山模型上进行实现，再迁移至向量化模型。\n\n## 如何为函数适配向量化模型接口\n\n**以下本文的重点！**\n\n如果一个内置函数在 TiKV 中已经有了火山模型的实现，但没有向量化模型的实现，则可以迁移它。以 LogicalXor 内置函数为例，它之前并没有向量化的实现（当然现在 [有了](https://github.com/tikv/tikv/pull/5826)）。可以遵循以下步骤：\n\n### 1. 找到火山模型的实现\n\n在 `components/tidb_query/src/expr/scalar_function.rs` 中搜索 `LogicalXor`，可以发现这个函数的实现位于 `logical_xor` 函数：\n\n```rust\nLogicalXor => logical_xor,\n```\n\n接下来搜索 `fn logical_xor` 就可以定位到函数具体内容，位于 `builtin_op.rs`（PS：不同内置函数会在不同文件中，不要照搬）：\n\n```rust\npub fn logical_xor(&self, ctx: &mut EvalContext, row: &[Datum]) -> Result<Option<i64>> {\n    let arg0 = try_opt!(self.children[0].eval_int(ctx, row));\n    let arg1 = try_opt!(self.children[1].eval_int(ctx, row));\n    Ok(Some(((arg0 == 0) ^ (arg1 == 0)) as i64))\n}\n```\n\n### 2. 翻译为向量化实现\n\n阅读理解上面的代码，可知 `LogicalXor` 是一个二元内置函数。其中，第一个参数 `children[0]` 和第二个参数 `children[1]` 都是通过 `eval_int` 方式访问的，因此 `LogicalXor` 接受的两个参数都是 int 类型。最后，这个函数返回值是 `Result<Option<i64>>` 代表它计算结果也是 int 类型。可以由这些信息翻译为以下向量化计算代码，实现在 `components/tidb_query/src/rpn_expr/impl_op.rs` 文件中：\n\n \n```rust\n#[rpn_fn]\n#[inline]\npub fn logical_xor(arg0: &Option<Int>, arg1: &Option<Int>) -> Result<Option<Int>> {\n    // TODO\n}\n```\n\n\n> 注：`Int` 是 `i64` 的 Type Alias。你既可以写 `Int` 也可以写 `i64`，不过更推荐 `Int` 一些。你可以从[这里](https://github.com/tikv/tikv/blob/d019ccecefc260ff760a53b7b8742fb84ffca9b5/components/tidb_query/src/codec/data_type/mod.rs#L10)找到所有的 Type Alias。`eval_xxx` 函数与类型的对应关系如下表所示。\n\n| 火山模型函数名 | 对应参数类型 | 参数类型别名 |\n|:-- |:-- |:----- | \n| `eval_int` | `Int` | `i64`|\n| `eval_real` | `Real` | `ordered_float::NotNan<f64>`|\n|`eval_decimal` | `Decimal` |  \n|`eval_bytes` | `Bytes` | `Vec<u8>`|\n|`eval_time` | `DateTime` |  \n|`eval_duration` | `Duration` |  \n|`eval_json` | `Json` |  \n\n换句话说就是：向量化版本的 `logical_xor` 是一个接受两个参数且两个参数都是 Int 类型的函数，返回 Int，是不是非常直观呢？另外我们使用 `None` 来代表 SQL 中的 `NULL` 值，因此函数参数及返回值都是 `Option<Int>` 类型。\n\n最后照搬原来的内部实现（注意处理好 `None` / `Some` 的情况），这个函数就算完成了：\n\n```rust\n#[rpn_fn]\n#[inline]\npub fn logical_xor(arg0: &Option<Int>, arg1: &Option<Int>) -> Result<Option<Int>> {\n    Ok(match (arg0, arg1) {\n        (Some(arg0), Some(arg1)) => Some(((*arg0 == 0) ^ (*arg1 == 0)) as i64),\n        _ => None,\n    })\n}\n```\n\n你可能会问，不是说好了向量化计算是批量计算的吗，为什么向量化计算版本的代码没有接受数组，而只是接受单个值呢？原因在于 TiKV 向量化计算框架会自动基于你的这个基本实现，在编译期生成向量化计算版本，伪代码类似于这样：\n\n```rust\nfn logical_xor_vector_scalar(arg0: []Int, arg1: Int) -> []Int {\n  let r = vec![];\n  for i in 0..n {\n    r.push( logical_xor(arg0[i], arg1) );\n  }\n  return r;\n}\n \nfn logical_xor_scalar_vector(arg0: Int, arg1: []Int) -> []Int {\n  let r = vec![];\n  for i in 0..n {\n    r.push( logical_xor(arg0, arg1[i]) );\n  }\n  return r;\n}\n \nfn logical_xor_vector_vector(arg0: []Int, arg1: []Int) -> []Int {\n  let r = vec![];\n  for i in 0..n {\n    r.push( logical_xor(arg0[i], arg1[i]) );\n  }\n  return r;\n}\n \nfn logical_xor_scalar_scalar(arg0: Int, arg1: Int) -> []Int {\n  let r = vec![];\n  for i in 0..n {\n    r.push( logical_xor(arg0, arg1) );\n  }\n  return r;\n}\n```\n\n\n你只需要关注内置函数本身的逻辑实现，其他的全部自动搞定！这些所有的奥秘都隐藏在了 `#[rpn_fn]` 过程宏中。\n\n当然，上面的伪代码只是便于你进行理解。这个过程宏的实际实现并不是像上面这样粗暴地组装代码。它巧妙地利用了 Rust 的泛型机制，让编译器去生成不同个数参数情况下的最优实现。这里有点偏题就不继续展开细说了，我们后续的源码阅读文章对这个机制会有进一步分析，感兴趣的同学可以阅读代码自行学习。\n\n### 3. 增加函数入口\n\n目前只是提供了向量化版本的函数实现，但还需要告诉向量化计算框架，在遇到 LogicalXor 这个内置函数的时候，使用上向量化版本 `logical_xor` 的实现。这一步很简单，修改 `components/tidb_query/src/rpn_expr/mod.rs` 文件中的 `map_expr_node_to_rpn_func` 函数，增加一个对应关系即可：\n \n```rust\nScalarFuncSig::LogicalXor => logical_xor_fn_meta(),\n```\n\n注意，此处要为函数名加上 `_fn_meta` 后缀，从而用上 `#[rpn_fn]` 过程宏自动生成的向量化版本函数实现。不要问为什么，问就是约定 :D \n\n### 4. 撰写单元测试\n\n搜索 `ScalarFuncSig::LogicalXor` 可以找到火山模型下的该函数单元测试：\n\n \n```rust\n#[test]\nfn test_logic_op() {\n    let tests = vec![\n        ...\n        (\n            ScalarFuncSig::LogicalXor,\n            Datum::I64(1),\n            Datum::I64(1),\n            Some(0),\n        ),\n        (\n            ScalarFuncSig::LogicalXor,\n            Datum::I64(1),\n            Datum::I64(0),\n            Some(1),\n        ),\n        (\n            ScalarFuncSig::LogicalXor,\n            Datum::I64(0),\n            Datum::I64(0),\n            Some(0),\n        ),\n        (\n            ScalarFuncSig::LogicalXor,\n            Datum::I64(2),\n            Datum::I64(-1),\n            Some(0),\n        ),\n        (ScalarFuncSig::LogicalXor, Datum::I64(0), Datum::Null, None),\n        (ScalarFuncSig::LogicalXor, Datum::Null, Datum::I64(1), None),\n    ];\n    let mut ctx = EvalContext::default();\n    for (op, lhs, rhs, exp) in tests {\n        let arg1 = datum_expr(lhs);\n        let arg2 = datum_expr(rhs);\n        ……\n    }\n}\n```\n\n\n这个测试覆盖挺完备的，因此可以直接拿样例来复用，作为向量化版本的单元测试。向量化版本单元测试中不再使用 Datum 等结构，而是可以直接用最原始的基础数据结构 `Option<Int>`，配上 `RpnFnScalarEvaluator` 进行执行，代码如下：\n\n \n```rust\n#[test]\nfn test_logical_xor() {\n    let test_cases = vec![\n        (Some(1), Some(1), Some(0)),\n        (Some(1), Some(0), Some(1)),\n        (Some(0), Some(0), Some(0)),\n        (Some(2), Some(-1), Some(0)),\n        (Some(0), None, None),\n        (None, Some(1), None),\n    ];\n    for (arg0, arg1, expect_output) in test_cases {\n        let output = RpnFnScalarEvaluator::new()\n            .push_param(arg0)\n            .push_param(arg1)\n            .evaluate(ScalarFuncSig::LogicalXor)\n            .unwrap();\n        assert_eq!(output, expect_output);\n    }\n}\n```\n\n如果原来火山模型实现的单元测试不完备，那么请在你的向量化实现中的单元测试中补充更多测试样例，尽可能覆盖所有分支条件。你也可以从 TiDB 的实现中迁移测试样例。注意，测试的目标是要检测实现是否符合预期，预期的是 TiKV 实现与 TiDB 实现能输出一样的结果，因此 TiDB 的输出是标准输出，不能由你自己来决定这个函数的标准输出。\n\n不过，有些情况下 TiDB 的输出可能与 MySQL 不一致，你可以选择与 TiDB 行为保持一致，也可以选择与 MySQL 行为保持一致，但都需要在 TiDB 中开 issue 汇报这个行为不一致情况。\n\n### 5. 运行测试\n\n至此，这个函数已经可以工作起来了，可以运行单元测试看一下：\n\n```\nmake dev\n```\n\n或者干脆只跑刚才写的这个测试：\n\n```\nEXTRA_CARGO_ARGS=\"test_logical_xor\" make dev\n```\n\n**测试通过就可以提 PR 了。注意要在 PR 的开头写上 `PCP #5751` 指明这个 PR 对应的性能挑战赛题目，不然合了是得不到积分的。另外我们鼓励每个 PR 都专注于做一件事情，所以请尽量不要在同一个 PR 内迁移或实现多个内置函数，否则只能得到一次 50 积分。**\n\n### 6. 运行下推测试\n\n众所周知，手工编写的测试样例往往会遗漏一些考虑欠缺的边缘情况，并且可能由于犯了一些错误，测试的预期输出实际与 TiDB 不一致。为了能覆盖这些边缘情况，进一步确保 TiKV 中的内置函数实现与 TiDB 的实现一致，我们有一批使用 [randgen](https://github.com/MariaDB/randgen) 自动生成的下推测试，位于 [https://github.com/tikv/copr-test](https://github.com/tikv/copr-test)。不管你是在 TiKV 中引入一个新的函数实现，还是迁移一个现有实现，都需要确保能跑过这个测试。流程如下：\n\n1.  需要确保你新实现的函数在 [copr-test](https://github.com/tikv/copr-test) 项目的 [push-down-test/functions.txt](https://github.com/tikv/copr-test/blob/master/push-down-test/functions.txt) 文件中，如果没有的话需要往 [copr-test](https://github.com/tikv/copr-test) 项目提 PR 将函数加入测试列表中。你需要将 SQL 里的函数名追加在文件中，或者可以参考 [all_functions_reference.txt](https://github.com/tikv/copr-test/blob/master/push-down-test/all_functions_reference.txt) 文件，这个文件里列出了所有可以写的函数名，从中挑出你的那个函数名，加入 [push-down-test/functions.txt](https://github.com/tikv/copr-test/blob/master/push-down-test/functions.txt)。\n\n2.  假设 [copr-test](https://github.com/tikv/copr-test) 中提的 PR 是 #10，则在你之前提的 TiKV PR 中回复 `@sre-bot /run-integration-copr-test copr-test=pr/10` 运行下推测试。如果你的函数之前已经在 [push-down-test/functions.txt](https://github.com/tikv/copr-test/blob/master/push-down-test/functions.txt) 列表中了，可以直接回复 `@sre-bot /run-integration-copr-test` 运行下推测试。\n\n当然，我们更推荐你能直接往 [copr-test](https://github.com/tikv/copr-test) 中添加人工编写的测试，更准确地覆盖边缘情况，具体方式参见 [copr-test](https://github.com/tikv/copr-test) 的 README。\n\n### 7. 在 TiDB 中增添签名映射\n\n如果上一步 copr-test 的测试挂了，一般来说有两种情况，一种情况是内置函数的实现有问题，被 copr-test 测了出来，另一种情况是你新实现的内置函数在 TiDB 侧还未建立函数签名与下推枚举签名 `ScalarFuncSig` 之间的映射关系。后者会在测试中产生 “unspecified PbCode” 错误，非常容易辨别。如果出现了这种情况，大家可以参考 [https://github.com/pingcap/tidb/pull/12864](https://github.com/pingcap/tidb/pull/12864) 的做法，为 TiDB 提 PR 增添相应内置函数的 PbCode 映射。添加完毕之后，可以在 TiKV PR 中回复 `@sre-bot /run-integration-copr-test copr-test=pr/X tidb=pr/Y`（其中 `X` 是你提的 copr-test PR 号，`Y` 是你提的 TiDB PR 号）进行联合测试。\n\n## 完成！\n\n至此，你新实现的内置函数有了单元测试，也有了与 TiDB 的集成下推测试，是一个合格的 PR 了，可以接受我们的 review。在 merge 后，你就能拿到相应的积分，积分可以在赛季结束后兑换 [TiDB 限量周边礼品](https://pingcap.com/community-cn/tidb-performance-challenge/)！\n\n最后欢迎大家加入 [TiDB Community Slack Workspace](https://join.slack.com/t/tidbcommunity/shared_invite/enQtNzc0MzI4ODExMDc4LWYwYmIzMjZkYzJiNDUxMmZlN2FiMGJkZjAyMzQ5NGU0NGY0NzI3NTYwMjAyNGQ1N2I2ZjAxNzc1OGUwYWM0NzE) 和 [tikv-wg Slack Workspace](http://tikv.org/chat)，参赛过程中遇到任何问题都可以直接通过 **#performance-challenge-program** channel 与我们取得联系。","date":"2019-11-11","author":"Wish","fillInMethod":"writeDirectly","customUrl":"how-to-join-in-the-tidb-performance-challenge-program","file":null,"relatedBlogs":[]},{"id":"Blogs_186","title":"让数据库运行在浏览器里？TiDB + WebAssembly 告诉你答案","tags":["WebAssembly","SQL","Go","MySQL","TiDB"],"category":{"name":"社区动态"},"summary":"今天的 TiDB 可以直接运行在浏览器本地。打开浏览器，你可以直接创建数据库，对数据进行增删改查。关掉浏览器，一切都消失了，干净绿色环保。","body":"一直以来都有个梦想：\n\n希望有一个数据库能够弹性扩展（分布式）到成百上千节点的规模，易于学习和理解，可以运行在私有云、公有云、Multi-Cloud、Kubernetes，也能够跑在嵌入式设备（比如树莓派）上，更酷的是也能够直接运行在浏览器里，而且不需要任何浏览器扩展（Extension），变成「口袋数据库」，就像那部电影《蚁人》。\n\n**今天，这一切都变成了现实：[TiDB](https://github.com/pingcap/tidb) 可以直接运行在浏览器本地。打开浏览器，你可以直接创建数据库，对数据进行增删改查。关掉浏览器，一切都消失了，干净绿色环保——**\n\n首先在笔记本浏览器打开 [play.pingcap.com](https://play.pingcap.com)（这里用的是 MacOS 上面的 Chrome，不确定其它浏览器是否正常），可能需要几秒来加载页面，然后就能看到熟悉的 Shell 了。现在来试试几个 SQL 语句吧！由于 TiDB 基本兼容 MySQL 协议和语法，因此我们可以用熟悉的 MySQL 风格操作，如下图所示：\n\n![图 1 在浏览器上运行 TiDB](https://img1.www.pingcap.com/prod/demo_1_9544be8472.gif)\n\n<div class=\"caption-center\">图 1 在浏览器上运行 TiDB</div>\n\n**是不是很酷？无痛体验 SQL 的时代到了。**\n\n**更酷的是，这一切都运行在浏览器本地，删库再也不用跑路了 😈**\n\n有了这些，那么是时候给在线学习 SQL 教程的网站加点功能了，比如在文字教程时，同步运行 SQL 语句。这里有个简单的 [演示](https://tour.pingcap.com/)：\n\n![图 2 SQL 教程网站演示](https://img1.www.pingcap.com/prod/demo_2_d6b04da603.png)\n\n<div class=\"caption-center\">图 2 SQL 教程网站演示</div>\n\n**那么在浏览器里面运行数据库还有哪些好处呢？**\n\n还记得你安装配置数据库的痛苦吗？从此以后，每个人随时随地都可以拥有一个数据库，再也没有痛苦的安装过程，再也不用痛苦的配置参数，随时享受写 SQL 的快感。也许我们不再需要 indexdb 了，SQL 是更高级的 API，TiDB 使得「一次编写、到处运行」变成了现实。\n\n当然，你一定很好奇这一切是怎么实现的：\n\n+ 首先要感谢 Go team 让 Go 语言支持了 WebAssembly（Wasm），这是近期最让我兴奋的特性之一，它让在浏览器里运行 Go 语言编写的应用程序成为了现实；\n\n+ 然后感谢 PingCAP 的开源分布式数据库 TiDB。我们把 TiDB 编译成 Wasm，在浏览器里直接运行生成的 Wasm 文件，这就使得在浏览器里运行一个数据库成为了现实。如果没有记错，TiDB 好像是 Go 语言编写的第一个可以在浏览器里面运行的 SQL 数据库；\n\n+ 特别感谢参加 [TiDB Hackathon 2019](https://github.com/pingcap/presentations/blob/master/hackathon-2019/hackathon-2019-projects.md) 的选手和大家各种有趣的想法，尤其感谢 Ti-cool 团队，在他们的努力下这一切变成了现实，该项目获得了 Hackathon 二等奖，现场评委团老师们也感到眼前一亮，对它的快速落地充满了期待！​\n\n>“TiDB-Wasm 极大降低了用户体验 TiDB 能力和初步验证 SQL 兼容性的门槛，使用体验就像 golang playground 一样流畅，Wasm 的出现也为 TiDB 文档中心的建设提出了新的思路，也许不久的将来，TiDB 用户可以像 golang 一样，在阅读文档的同时，就能够在页面上尝试实际操作的体验。我们也期待 Wasm 能够持续发展，实现 TiKV 的沙箱化运行，提供更贴近真实运行场景的 playground，甚至在自动化运维管理方向上贡献更新奇思路。”\n>\n>——李凯（美团 | 数据库团队负责人）\n>\n>“刚看到这个项目的时候真的眼前一亮，这是一个非常酷的创意，而且真的对 DBA 运维管理 TiDB 有非常大的帮助，个人强烈希望这个项目能尽快落地支持！\n>\n>目前我们公司使用 TiDB 时，有很大一部分是由现在业务改造接入，但是面临的一个很重要的问题是 应用原来都是基于 MySQL 开发，虽然 TiDB 在 SQL 语法兼容上做了很多的工作，但是仍然未能 100% 覆盖，所以业务切换前我们都必须要进行 SQL 语法兼容性测试及数据准确性校验。由于 TiDB 的部署都是在线上服务器，基于数据安全，我们的生产和办公网环境是隔离的，要实现上面的需求，目前我们有如下几种方式：a) 研发同学自己写脚本连接查看；b)DBA 登录集群协助验证；c)开发专用查询平台支持。目前这这几种方式都不够安全且效率低下。随着我们维护的 TiDB 集群越来越多，DBA 的对这种低效工作不堪其烦，急需相关工具支持，而 TiDB-Wasm 无疑会解决这种问题，所以希望官方能够重视这个项目，并尽快落地实现。”\n>\n>——于伯伟（58集团 | 数据库高级经理）\n>\n>\n>“Wasm 是一个神奇的技术，也许诞生初期的目的只是为了解决 js 运行速度以及其他语言如何操作 html 的问题，但现在大家在用这种技术广泛尝试各种可能。TiDB-Wasm 就是一个很好的尝试，不仅大幅度降低了新人使用 TiDB 的难度、也给文档展示提供了神奇的操作环境、还能大幅度降低应用开发者本机调试环境的构建难度。相信这个思路能给其他服务端的软件一个很好的启发。”\n>\n>——李道兵（京东云 | 高级总监）\n>\n>“很多用户希望初步了解 TiDB 但是苦于找不到简单即用的线下环境，这导致他们还未入门就已经放弃。TiDB-Wasm 有望彻底解决这个问题。基于 TiDB-Wasm，用户可以方便的开启 session 来探索 TiDB 的特性和功能，调试 TiDB 的行为，以及对比 TiDB 与 MySQL 等数据库在 SQL 语法、加锁行为、事务隔离等级等细节上的差异，从而帮助用户更深入的理解 TiDB。对官方而言，甚至可以把路由、计算、存储层的扩容缩容、迁移等最佳实践集成到该平台并可视化该过程，从而给用户更真实、直观的感受。这将是一款令人激动的产品，它将促进 TiDB 社区更加繁荣，也将让所有 TiDB 用户受益！”\n>\n>——赵应钢（美团点评 | 分布式数据库平台开发和运维负责人，研究员）\n>\n>“TiDB-Wasm 这个项目成功地将 TiDB 移植到了 Wasm，证明了 TiDB 编译到 Wasm 的可行性，同时也反映了 WebAssembly 已走向成熟，相信后面会有更多项目移植到浏览器里运行。目前项目还处于 demo 阶段，后续如果将项目继续落地，在上面添加更多功能，比如使用 indexedDB 让数据持久化，比如使用 webrtc 之类的技术让不同浏览器中的 TiDB 可以进行 P2P 通讯，实现分布式浏览器数据库，我非常期待这些实现。”\n>\n>——侯圣文（贝壳找房 | 数据技术总监）\n>\n>“TiDB-Wasm 让我看到了 TiDB 的更多可能性。Wasm 本身是一个很有野心和想象力的技术，极大的扩展了前端的能力，可能大家都玩过类似 go playgound, rust playground 这类 web 的可交互体验平台，TiDB-Wasm 更进一步让用户甚至在离线环境下就能直接体验，可谓最极致的易用。从实用角度上来看，除了能成为一个浏览器中的 REPL 供配合文档快速体验和实验之外，TiDB-Wasm 甚至未来还可以作为 js 的 localStorage API 的很好的补充，为 js 生态提供一个 SQLite 之外的高性能本地数据库……当然，在体验上仍然有很多可以优化的地方，例如给 binary 瘦身，加入集群模式支持等。总体来说这是一个很好玩的项目。”\n>\n>——黄东旭（PingCAP | 联合创始人兼 CTO）\n>\n>“这个项目可以说集新颖性和实用性于一身，用一种很巧妙的方式，将数据库这样硬核的基础架构和炫酷的前端领域搭上关系，接下来二者就可以碰撞出各种火花。最直接的用法是大大降低用户体验 TiDB 的成本，只需要一个浏览器页面和等待下载 Binary 的时间，完全不需要安装部署，就可以体验 TiDB 基本的功能，无论是嵌入到文档中快速运行实例还是作为 Playgroud 网站让用户自由发挥，都非常合适。再扩展想一下，TiDB 可以看作 MySQL 的替代品，那么很多 MySQL 的教学网站也可以用这个 Wasm 来提升教学体验。当然，Demo 中演示的 SQL 教学只是最基本的玩法，有了这个东西，我们可以说：恭喜前端圈有了一个 JS 版本的 MySQL。相信前端的同学能把它玩出花来。一句话总结：这绝对是一个叫好又叫座的项目。”\n>\n>——申砾（PingCAP | Engineering VP）\n\n**接下来我们可以试试更多有趣的想法：**\n\n+ 让更多的在线 SQL 教程都可以直接运行。\n+ 让 TiDB 运行在 Go Playground 上，或许需要 Go team 的帮助。\n+ 支持持久化数据库，我们已经有了云计算、边缘计算，为什么不能有浏览器计算呢？\n+ ……\n\n还有好多想法我们将在接下来的文章里介绍。如果你有新的、有趣的想法，欢迎 [联系我们](mailto:info@pingcap.com)。\n\n**下一篇文章将由 Ti-cool 团队成员介绍整个项目的实现原理和后续改进工作，敬请期待！如果你已经等不及了，可以在这里直接看 [源码实现](https://github.com/pingcap/tidb/pull/13069)，祝大家玩得开心！**","date":"2019-11-05","author":"Max","fillInMethod":"writeDirectly","customUrl":"tidb-in-the-browser-running-a-golang-database-on-wasm","file":null,"relatedBlogs":[]},{"id":"Blogs_44","title":"TiKV 项目首个 SIG 成立，一起走上 Contributor 进阶之路吧！","tags":["社区","社区动态"],"category":{"name":"社区动态"},"summary":"今天是 1024 程序员节，我们正式成立 TiKV 项目的首个 SIG —— Coprocessor SIG，希望对 TiKV 项目感兴趣的小伙伴们都能加入进来，探索硬核的前沿技术，交流切磋，一起走上 Contributor 的进阶之路！","body":"社区是一个开源项目的灵魂，随着 TiDB/TiKV [新的社区架构升级](https://pingcap.com/blog-cn/tidb-community-upgrade/)， TiKV 社区也计划逐步成立更多个 Special Interest Group（SIG ）吸引更多社区力量，一起来改进和完善 TiKV 项目。SIG  将围绕着特定的模块进行开发和维护工作，并对该模块代码的质量负责。\n\n今天是 1024 程序员节，我们正式成立 TiKV 项目的首个 SIG —— Coprocessor SIG，希望对 [TiKV 项目](https://github.com/tikv/tikv) 感兴趣的小伙伴们都能加入进来，探索硬核的前沿技术，交流切磋，一起走上 Contributor 的进阶之路！\n\n## Coprocessor 模块是什么？\n\n为了提升数据库的整体性能，TiDB 会将部分计算下推到 TiKV 执行，即 TiKV 的 Coprocessor 模块。本次成立的 Coprocessor SIG 就聚焦在 TiKV 项目 Coprocessor 模块。本 SIG 的主要职责是对 Coprocessor 模块进行未来发展的讨论、规划、开发和维护。\n\n## 如何加入 Coprocessor SIG？\n\n**社区的 Reviewer 或更高级的贡献者（Committer，Maintainer）将提名 Active Contributor 加入 Coprocessor SIG。Active Contributor 是对于 TiKV Coprocessor 模块或者 TiKV 项目有浓厚兴趣的贡献者，在过去 1 年为 TiKV 项目贡献超过 8 个 PR。**\n\n加入 SIG 后，Coprocessor SIG Tech Lead 将指导成员完成目标任务。在此过程中，成员可以从 Active Contributor 逐步晋升为 Reviewer、Committer 角色，解锁更多角色权利&义务。\n\n+ Reviewer：从 Active Contributor 中诞生，当 Active Contributor 对 Coprocessor 模块拥有比较深度的贡献，并且得到 2 个或 2 个以上 Committer 的提名时，将被邀请成为该模块的 Reviewer，主要权利&义务：\n    - 参与 Coprocessor PR Review 与质量控制；\n    - 对 Coprocessor 模块 PR 具有有效的 Approve / Request Change 权限；\n    - 参与项目设计决策。\n+ Committer：资深的社区开发者，从 Reviewer 中诞生。当 Reviewer 对 Coprocessor  模块拥有非常深度的贡献，或者在保持 Coprocessor  模块 Reviewer 角色的同时，也在别的模块深度贡献成为了 Reviewer，这时他就在深度或者广度上具备了成为 Committer 的条件，只要再得到 2 个或 2 个以上 Maintainer 的提名时，即可成为 Committer，主要权利及义务：\n    - 拥有 Reviewer 具有的权利与义务；\n    - 整体把控项目的代码质量；\n    - 指导 Contributor 与 Reviewer。\n\n## 工作内容有哪些？\n\n1. 完善测试\n\n\t* 为了进一步提高 Coprocessor 的集成测试覆盖率，TiKV 社区开源了 copr-test 集成测试框架（github.com/tikv/copr-test），便于社区为 Coprocessor 添加更多集成测试；\n\t\n\t* 从 TiDB port 的函数需要同时 port 单元测试，如果 TiDB 的单元测试没有覆盖所有的分支，需要补全单元测试；\n\t\n\t* Expression 的集成测试需要构造使用这个 Expression 的算子进行测试。\n\n2. 提升代码质量\n\n\t* Framework: 计算框架改进，包括表达式计算框架、算子执行框架等；\n\t\n\t* Executor: 改进现有算子、与 TiDB 协作研发新算子；\n\t\n\t* Function: 维护现有的 UDF / AggrFn 实现或从  TiDB port 新的 UDF / AggrFn 实现；\n\t\n\t* 代码位置：[https://github.com/tikv/tikv/tree/master/components/tidb_query](https://github.com/tikv/tikv/tree/master/components/tidb_query)\n\n3. 设计与演进 Proposal\n\n4. Review 相关项目代码\n\n## 如何协同工作？\n\n1. 为了协同效率，我们要求 SIG 成员遵守一致的代码风格、提交规范、PR Description 等规定。具体请参考 [文档](https://github.com/tikv/tikv/blob/master/CONTRIBUTING.md)。\n\n\n2. 任务分配方式\n\n\t* SIG Tech Lead 在 github.com/tikv/community 维护公开的成员列表与任务列表链接；\n\t\n\t* 新加入的 SIG 成员可有 2 周时间了解各个任务详情并认领一个任务，或参与一个现有任务的开发或推动。若未能在该时间内认领任务则会被移除 SIG；\n\t\n\t* SIG 成员需维持每个月参与开发任务，或参与关于现有功能或未来规划的设计与讨论。若连续一个季度不参与开发与讨论，视为不活跃状态，将会被移除 SIG。作为 acknowledgment，仍会处于成员列表的「Former Member」中。\n\n3. 定期同步进度，定期周会\n\n\t* 每 2 周以文档形式同步一次当前各个项目的开发进度；\n\t\n\t* 每 2 周召开一次全组进度会议，时间依据参会人员可用时间另行协商。目前没有项目正在开发的成员可选择性参加以便了解各个项目进度。若参与开发的成员不能参加，需提前请假且提前将自己的月度进度更新至文档；\n\t\n\t* 每次会议由一名成员进行会议记录，在会议结束 24 小时内完成会议记录并公开。会议记录由小组成员轮流执行；\n\t\n\t*  Slack：[https://tikv-wg.slack.com](https://tikv-wg.slack.com/join/shared_invite/enQtNTUyODE4ODU2MzI0LWVlMWMzMDkyNWE5ZjY1ODAzMWUwZGVhNGNhYTc3MzJhYWE0Y2FjYjliYzY1OWJlYTc4OWVjZWM1NDkwN2QxNDE)（Channel #copr-sig-china）\n\t\n4. 通过更多线上、线下成员的活动进行交流合作。\n\n## Coprocessor SIG 运营制度\n\n1. 考核 & 晋升制度\n\n\ta. Coprocessor SIG Tech Lead 以月为单位对小组成员进行考核，决定成员是否可由 Active Contributor 晋升为 Reviewer：\n\t\n    + 熟悉代码库；\n    + 获得至少 2 位 TiKV Committer 的提名；\n    + PR 贡献满足以下任意一点：\n        - Merge Coprocessor PR 总数超过 10 个；\n        - Merge Coprocessor PR 总行数超过 1000 行；\n        - 已完成一项难度为 Medium 或以上的任务；\n        - 提出设计想法并得到采纳成为可执行任务超过 3 个。\n\t\n\tb. Coprocessor SIG Tech Lead 和 TiKV Maintainer 以季度为单位对小组成员进行考核，决定成员是否可由 Reviewer 晋升为 Committer：\n\t\n\t+ 表现出良好的技术判断力；\n\t+ 在 TiKV / PingCAP 至少两个子项目中是 Reviewer；\n\t+ 获得至少 2 位 TiKV Maintainer 的提名；\n\t+ 至少完成两项难度为 Medium 的任务，或一项难度为 High 的任务；\n\t+ PR 贡献满足以下至少两点：\n\t    - 半年内 Merge Coprocessor PR 总行数超过 1500 行；\n\t    - 有效 Review Coprocessor PR 总数超过 10 个；\n\t    - 有效 Review Coprocessor PR 总行数超过 1000 行。\n\n2. 退出制度\n\n\ta. SIG 成员在以下情况中会被移除 SIG，但保留相应的 Active Contributor / Reviewer / Committer 身份：\n\t\n\t   + 作为新成员未在指定时间内认领任务；\n\t   + 连续一个季度处于不活跃状态。\n\t\n\tb. Reviewer 满足以下条件之一会被取消 Reviewer 身份且收回权限（后续重新考核后可恢复）：\n\t\n\t   + 超过一个季度没有 review 任何 Coprocessor 相关的 PR；\n\t   + 有 2 位以上 Committer 认为 Reviewer 能力不足或活跃度不足。\n\n3. Tech Lead 额外承担的职责\n\n   + SIG 成员提出的问题需要在 2 个工作日给出回复；\n   + 及时 Review 代码；\n   + 定时发布任务（如果 SIG 成员退出后，未完成的任务需要重新分配）。\n\n## 小结\n\n通过上文相信大家对于 Coprocessor SIG 的工作内容、范围、方式以及运营制度有了初步的了解。如果你是一个开源爱好者，想要参与到一个工业级的开源项目中来，或者想了解社区的运行机制，想了解你的代码是如何从一个想法最终发布到生产环境中运行，那么加入 Coprocessor SIG 就是一个绝佳的机会！\n\n**如果你仍对 SIG 有些疑问或者想要了解更多学习资料，欢迎加入 [tikv-wg.slack.com](https://tikv-wg.slack.com/join/shared_invite/enQtNTUyODE4ODU2MzI0LWVlMWMzMDkyNWE5ZjY1ODAzMWUwZGVhNGNhYTc3MzJhYWE0Y2FjYjliYzY1OWJlYTc4OWVjZWM1NDkwN2QxNDE) 哦～**","date":"2019-10-24","author":"Long Heng","fillInMethod":"writeDirectly","customUrl":"tikv-coprocessor-sig","file":null,"relatedBlogs":[]},{"id":"Blogs_62","title":"新架构、新角色：TiDB Community Upgrade！","tags":["社区","社区动态"],"category":{"name":"社区动态"},"summary":"TiDB 社区已经逐渐成熟，但是随着社区的发展壮大，我们逐渐感受到了现在社区架构上的一些不足。经过一系列的思考和总结，我们决定升级和调整目前社区组织架构，引入更多的社区角色和社区组织，以便更好的激发社区活力，维护积极健康的社区环境。","body":"经过几年的发展，TiDB 社区已经逐渐成熟，但是随着社区的发展壮大，我们逐渐感受到了现在社区架构上的一些不足。经过一系列的思考和总结，我们决定升级和调整目前社区组织架构，引入更多的社区角色和社区组织，以便更好的激发社区活力，维护积极健康的社区环境。\n\n## 老社区架构\n\n下图是之前官网上的社区架构图：\n\n![图 1 老社区架构](https://img1.www.pingcap.com/prod/1_a6cb9452b6.png)\n\n<div class=\"caption-center\">图 1 老社区架构</div>\n\n老社区架构主要面向 TiDB 开发者社区（Developer Group），主要角色有 Maintainer、Committer、Contributor 等，其中：\n\n* Committer：由 Maintainer 或 PMC 推荐，是对 TiDB 有突出贡献的 Contributor。需要独立完成至少一个 feature 或修复重大 bug。\n\n* Maintainer：项目的规划和设计者，拥有合并主干分支的权限，从 Committer 中产生。他们必须对子项目的健康表现出良好的判断力和责任感。维护者必须直接或通过委派这些职责来设置技术方向并为子项目做出或批准设计决策。\n\n可以看到老社区架构屏蔽了日益壮大的、对产品打磨升级至关重要的 TiDB 用户群体，并且老架构中对于开发者社区角色的职责、角色之间关系的表述都比较简单，所以我们在新社区架构中做了一些加法，将 TiDB 用户社区纳入进来的同时，对 TiDB 开发者社区的每个角色定义、权责又做了明确的界定，同时也增加了一些新角色、新组织，下面让我们来详细地看一看。\n\n## 新社区架构\n\n### 变化 1：将 TiDB 用户社区纳入整体社区架构\n\n随着 TiDB 产品的成熟，TiDB 用户群体愈发壮大，用户在使用过程中遇到的问题反馈及实践经验，对于 TiDB 产品的完善及应用推广有着不可忽视的重要作用。因此我们此次正式将 TiDB 用户社区（TiDB User Group，简称 TUG）纳入新的社区架构中来，希望用户与开发者有更好的交流互动，一起推动 TiDB 社区的健康发展。\n\n![图 2 新社区架构之 User Group](https://img1.www.pingcap.com/prod/2_3b4f7d4199.png)\n\n<div class=\"caption-center\">图 2 新社区架构之 User Group</div>\n\nTiDB User Group（TUG）是由 TiDB 用户发起的独立、非盈利的第三方组织，用户实行自我管理，旨在加强 TiDB 用户之间的交流和学习。TUG 的形式包括但不限于线上问答和技术文章分享、线下技术沙龙、走进名企、官方互动活动等等。TUG 成员可以通过线上、线下的活动，学习前沿技术知识，发表技术见解，共同建设 TiDB 项目。更多信息可以登陆 TUG 问答论坛 [asktug.com](https://asktug.com) 查看。\n\n### 变化 2：Active Contributor 和 Reviewer\n\n![图 3 新社区架构之 Active Contributor、Reviewer](https://img1.www.pingcap.com/prod/3_1f59ea151f.png)\n\n<div class=\"caption-center\">图 3 新社区架构之 Active Contributor、Reviewer</div>\n\n上图反映了这次社区架构升级的第 2 个变化：在开发者社区中，新增了 Reviewer 和 Active Contributor 的角色。\n\nActive Contributor 是一年贡献超过 8 个 PR 的 Contributor。Reviewer 从 Active Contributor 中诞生，具有 Review PR 的义务，并且对 TiDB 或者 TiKV 某个子模块的 PR 的点赞（LGTM）有效。关于这些角色，我们将在后文介绍 Special Interest Group 时更详细地介绍。\n\n### 变化 3：Special Interest Group\n\n让我们把开发者社区架构图放大再看看：\n\n![图 4 新社区架构之 Special Interest Group](https://img1.www.pingcap.com/prod/4_8074e6e951.png)\n\n<div class=\"caption-center\">图 4 新社区架构之 Special Interest Group</div>\n\n上图展示了以垂直的视角来细看开发者社区的整体架构，反映了这次社区架构升级的第 3 个变化：引入了 “专项兴趣小组”（Special Interest Group，简称 SIG）。\n\n专项兴趣小组主要负责 TiDB/TiKV 某个模块的开发和维护工作，对该模块代码的质量负责。我们将邀请满足条件的 Active Contributor 加入专项兴趣小组，开发者们将在专项兴趣小组中获得来自 Tech Lead 们的持续指导，一边锻炼技术能力，一边优化和完善该模块。社区开发者们可通过专项兴趣小组逐渐从初始的 Active Contributor 成长为受到社区认可的 Reviewer、Committer 和 Maintainer。一般而言每个专项兴趣小组都会周期性的组织会议，讨论最近进展和遇到的问题，所有的会议讨论都公开在社区上，方便感兴趣的同学一起参与和讨论。\n\n具体可参考目前我们正在运营的表达式专项兴趣小组：[Expression Special Interest Group](https://github.com/pingcap/community/tree/master/special-interest-groups/sig-exec)（注：该 SIG 在 2020 年升级为 Execution Special Interest Group，即 Exec SIG）。\n\n另外这张图也反映了社区角色和专项兴趣小组的关系，我们来仔细看看 SIG 中的社区角色：\n\n1.  Active Contributor\n    + 即一年贡献超过 8 个 PR 的 Contributor。\n    + 如果要加入某个 SIG，某个 Contributor 需要在 1 年内为该 SIG 所负责的模块贡献超过 8 个以上的 PR，这样即可获得邀请，加入该 SIG 进行针对性的学习和贡献。\n\n2.  Reviewer\n    + 隶属于某个 SIG，具有 Review PR 的义务。\n    + Reviewer 从 Active Contributor 中诞生，当 Active Contributor 对该模块拥有比较深度的贡献，并且得到 2 个或 2 个以上 Committer 的提名时，将被邀请成为该模块的 Reviewer。\n    + Reviewer 对该模块代码的点赞（LGTM）有效（注：TiDB 要求每个 PR 至少拥有 2 个 LGTM 后才能够合并到开发分支）。\n\n3.  Tech Lead\n    + 即 SIG 的组织者，负责 SIG 的日常运营，包括组织会议，解答疑问等。\n    + Tech Lead 需要为 SIG 的管理和成长负责，责任重大。目前暂时由 PingCAP 内部同事担任，将来可由社区开发者一起担任，和 PingCAP 同事一起为 SIG 的进步而努力。\n\n再来看看另外两个角色：\n\n1. Committer\n    + 资深的社区开发者，从 Reviewer 中诞生。\n    + 当 Reviewer 对该模块拥有非常深度的贡献，或者在保持当前模块 Reviewer 角色的同时，也在别的模块深度贡献成为了 Reviewer，这时他就在深度或者广度上具备了成为 Committer 的条件，只要再得到 2 个或 2 个以上 Maintainer 的提名时，即可成为 Committer。\n\n2. Maintainer\n    + 重度参与 TiDB 社区的开发者，从 Committer 中诞生，对代码 repo 拥有写权限。\n\n>以上社区角色的详细的定义和权责内容可以在 [这里](https://pingcap.com/community-cn/developer-group/) 查看。\n\n### 变化 4：Working Group\n\n\n![图 5 新社区架构之 Working Group](https://img1.www.pingcap.com/prod/5_418608c98a.png)\n\n<div class=\"caption-center\">图 5 新社区架构之 Working Group</div>\n\n第 4 个变化是开发者社区架构中引入了 “工作小组”（Working Group，简称 WG）。工作小组是由为了完成某个特定目标而聚集在一起的社区开发者与 PingCAP 同事一起成立。为了完成目标，有些工作小组可能跨越多个 SIG，有些小组可能只会专注在某个具体的 SIG 中做某个具体的事情。\n\n工作小组具有生命周期，一旦目标完成，工作小组即可解散。工作小组运营和管理的唯一目标是确保该小组成立时设置的目标在适当的时间内完成。一般而言，工作小组也会有周期性的会议，用于总结目前项目进展，确定下一步实施方案等。\n\n可参考目前我们正在运营的表达式工作小组：[Vectorized Expression Working Group](https://github.com/pingcap/community/blob/master/working-groups/wg-vec-expr.md)。\n\n## 总结和未来的工作\n\n总的来说，这次社区架构升级主要有如下改进：\n\n1. 引入了 TiDB 用户社区（TiDB User Group）。\n\n2. 引入了 Active Contributor、Reviewer 的社区角色。\n\n3. 引入了 Special Interest Group（SIG）。\n\n4. 引入了 Working Group（WG）。\n\n在社区运营方面，我们未来还将继续：\n\n1. 完善社区成员晋级的指导机制，让社区同学从 Contributor 成长到 Committer 或 Maintainer 有路可循。\n\n2. 让社区上的事情更加成体系，做事不乱。\n\n3. 让社区同学更有归属感，加强和其他社区成员的沟通。\n\n在未来，我们将陆续开放更多的专项兴趣小组和工作小组。在专项兴趣小组中，还将持续发放更多数据库相关的资料，帮助成员在专项兴趣小组中逐渐深度参与 TiDB 的开发工作。希望大家都能够多多参与进来，一起将 TiDB 打造成开源分布式关系型数据库的事实标准！","date":"2019-10-22","author":"Jian Zhang","fillInMethod":"writeDirectly","customUrl":"tidb-community-upgrade","file":null,"relatedBlogs":[]},{"id":"Blogs_153","title":"十分钟成为 Contributor 系列 | TiDB 向量化表达式活动第二弹","tags":["TiDB","社区","Contributor"],"category":{"name":"社区动态"},"summary":"在上篇文章中，我们介绍了 TiDB 如何实现表达式的向量化优化，以及社区同学如何参与这项工程。两周过去了，我们收到了很多来自社区小伙伴们的建议和反馈，今天在这里和大家分享一下活动进展和这些建议及反馈。","body":"在 [上篇文章](https://pingcap.com/blog-cn/10mins-become-contributor-of-tidb-20190916/) 中，我们介绍了 TiDB 如何实现表达式的向量化优化，以及社区同学如何参与这项工程。两周过去了，我们收到了很多来自社区小伙伴们的建议和反馈，今天在这里和大家分享一下活动进展和这些建议及反馈。\n\n## 活动进展\n\n**先来看看这两周的活动进展吧。截至 9 月 30 日中午，所有 Issue 中需要向量化的函数签名总共有 517 个，目前已完成 89 个，占总体的 17%。其中绝大多数的函数签名向量化都是由社区开发者们完成的，感谢大家的贡献！**\n\n各类型函数签名的完成度如下，我们通过这几个 Issue 来追踪向量化的工作进展，欢迎大家去里面挑选感兴趣的，还未被其他人认领的函数签名去实现：\n\n* [Date/Time builtin functions](https://github.com/pingcap/tidb/issues/12101) (7/65)\n\n* [Decimal builtin functions](https://github.com/pingcap/tidb/issues/12102) (7/31)\n\n* [Int builtin functions](https://github.com/pingcap/tidb/issues/12103) (22/187)\n\n* [JSON builtin functions](https://github.com/pingcap/tidb/issues/12104) (1/27)\n\n* [Real builtin functions](https://github.com/pingcap/tidb/issues/12105) (28/49)\n\n* [String builtin functions](https://github.com/pingcap/tidb/issues/12106) (19/113)\n\n* [Duration builtin functions](https://github.com/pingcap/tidb/issues/12176) (5/45)\n\n## FAQ\n\n**Q1：前期开发过程中，PR 很容易和主干代码冲突，如何解决？**\n\nA1：在前期的开发过程中，我们发现大家的 PR 冲突比较多，抱歉给大家的开发带来了不便。目前该问题已由 [PR/12395](https://github.com/pingcap/tidb/pull/12395) 解决。经过这个 PR 以后，所有表达式的开发接口和测试接口都被预先定义好了，避免了不同 PR 修改同一行代码造成频繁的冲突。大家后续开发时，可以直接修改这些预先定义好的接口的内部实现，参考：[PR/12400](https://github.com/pingcap/tidb/pull/12400)。\n\n**Q2：如何让测试框架只测试某个具体函数签名？**\n\nA2：我们在 [PR/12153](https://github.com/pingcap/tidb/pull/12153) 中，支持了以命令行变量的方式，如 -args \"builtinLog10Sig\"，让测试框架只跑被指定的函数，方便大家进行测试，更具体的使用方法请见此 PR 内的说明。\n\n**Q3：如何计算结果向量的 Null Bitmap？**\n\nA3：在 TiDB 中，我们使用一个 Bitmap 来标记 Column（也就是我们的“向量”） 中某个元素是否为 `NULL`，在向量化计算的函数中，经常会有如下处理 `NULL` 的需求： \n\n```\nfor rowID := range rows {\n    if child1.IsNull(rowID) || child2.IsNull(rowID) {\n        col.SetNull(rowID)\n        continue\n    }\n    // do something\n}\n\n```\n\n上面的计算逻辑没有正确性问题，但是不够高效。在 [PR/12034](https://github.com/pingcap/tidb/pull/12034) 里面，我们为 Column 添加了一个 `MergeNulls()` 的接口，用于快速完成上面这段计算 NULL Bitmap 的过程。出于性能考虑，建议大家尽可能使用这一接口来计算结果向量的 NULL Bitmap，示例如下：\n\n```\ncol.MergeNulls(child1, child2)\nfor rowID := range rows {\n    if col.IsNull(rowID) {\n        continue\n    }\n    // do something\n}\n```\n\n## 开发者社区\n\n如上面所说，在表达式向量化优化过程中的代码绝大多数都是由社区开发者们贡献的，具体来说是以下 Contributor（按照 PR 数排序，“*” 表示这次活动中新晋的 TiDB Contributor）：\n\n![](https://img1.www.pingcap.com/prod/1_00029996f3.png)\n\n再次感谢社区伙伴们的大力支持！也恭喜新晋 Contributor，当然 TiDB Contributor 专属马克杯也已经准备好啦，社区运营小姐姐将会统一邮寄给大家，敬请期待！\n\n在 TiDB 的 Expression Package 上，下面几位同学的 PR 贡献数已经超过了 8 个（包括向量化相关的 PR），达到了 Active Contributor 的要求，他们分别是：[jacklightChen](https://github.com/jacklightChen)，[tsthght](https://github.com/tsthght)，[tangwz](https://github.com/tangwz) 和 [b41sh](https://github.com/b41sh)，也恭喜他们！\n\n成为 Active Contributor 之后，如果继续为 Expression Package 贡献 PR，且合并的 PR 数量超过 20 个，就有机会获得提名成为 Expression Package [Reviewer](https://github.com/pingcap/community/blob/master/special-interest-groups/sig-exec/roles-and-organization-management.md#from-active-contributor-to-reviewer)。Expression Package 的 Reviewer 在技术上受到社区认可，其对 PR 的 review comments 具有技术公信力，可以和 TiDB 工程师一起 Review Expression 包的 PR，并拥有点赞的权限，当然还拥有持续发展成 TiDB Committer 的机会！\n\n## 未来工作\n\n[上篇文章](https://pingcap.com/blog-cn/10mins-become-contributor-of-tidb-20190916/) 中提到，我们成立了 [Vectorized Expression Working Group](https://github.com/pingcap/community/blob/master/working-groups/wg-vec-expr.md)，并在 slack - [tidbcommunity](https://pingcap.com/tidbslack) 中开放了 #wg-vec-expr 的公共 channel 供大家讨论问题，欢迎感兴趣的同学参与进来一起讨论表达式计算的向量化优化。目前表达式向量化重构的工作还在继续，欢迎各位新老 Contributor 持续的参与这项工程。\n\n此外，我们后续会优化升级 Community Organizer 组织架构，除了现在 Working Group 的组织以外，还会新增 Special Interest Group（简称 SIG)，负责专门维护和开发 TiDB 中某些具体模块，并将在国庆节后成立 Expression 的 SIG。届时将邀请 Expression Package 中 Active Contributor 及以上角色的同学参加。我们会在 Expression SIG 中为社区同学提供详尽的辅导，帮助 SIG 中的同学在提升自我，满足自己兴趣的同时，持续为 TiDB 贡献代码，和 TiDB 一起成长，敬请期待！  \n> 点击查看更多 [成为 Contributor 系列文章](https://pingcap.com/zh/blog/?tag=Contributor)","date":"2019-09-30","author":"Yuanjia Zhang","fillInMethod":"writeDirectly","customUrl":"10mins-become-tidb-contributor-20190930","file":null,"relatedBlogs":[]},{"id":"Blogs_46","title":"十分钟成为 Contributor 系列 | 助力 TiDB 表达式计算性能提升 10 倍","tags":["TiDB","社区","Contributor"],"category":{"name":"社区动态"},"summary":"最近我们扩展了 TiDB 表达式计算框架，增加了向量化计算接口，初期的性能测试显示，多数表达式计算性能可大幅提升，部分甚至可提升 1~2 个数量级。为了让所有的表达式都能受益，我们需要为所有内建函数实现向量化计算。","body":"最近我们扩展了 TiDB 表达式计算框架，增加了向量化计算接口，初期的性能测试显示，多数表达式计算性能可大幅提升，部分甚至可提升 1~2 个数量级。为了让所有的表达式都能受益，我们需要为所有内建函数实现向量化计算。\n\nTiDB 的向量化计算是在经典 Volcano 模型上的进行改进，尽可能利用 CPU Cache，SIMD Instructions，Pipeline，Branch Predicatation 等硬件特性提升计算性能，同时降低执行框架的迭代开销，这里提供一些参考文献，供感兴趣的同学阅读和研究：\n\n1.  [MonetDB/X100: Hyper-Pipelining Query Execution](http://cidrdb.org/cidr2005/papers/P19.pdf)\n\n2.  [Balancing Vectorized Query Execution with Bandwidth-Optimized Storage](https://dare.uva.nl/search?identifier=5ccbb60a-38b8-4eeb-858a-e7735dd37487)\n\n3.  [The Design and Implementation of Modern Column-Oriented Database Systems](https://www.nowpublishers.com/article/DownloadSummary/DBS-024)\n\n在这篇文章中，我们将描述：\n\n1.  如何在计算框架下实现某个函数的向量化计算；\n\n2.  如何在测试框架下做正确性和性能测试；\n\n3.  如何参与进来成为 TiDB Contributor。\n\n## 表达式向量化\n\n### 1. 如何访问和修改一个向量\n\n在 TiDB 中，数据按列在内存中连续存在 Column 内，Column 详细介绍请看：[TiDB 源码阅读系列文章（十）Chunk 和执行框架简介](https://pingcap.com/blog-cn/tidb-source-code-reading-10/)。本文所指的向量，其数据正是存储在 Column 中。\n\n我们把数据类型分为两种：\n\n1.  定长类型：`Int64`、`Uint64`、`Float32`、`Float64`、`Decimal`、`Time`、`Duration`；\n\n2.  变长类型：`String`、`Bytes`、`JSON`、`Set`、`Enum`。\n\n定长类型和变长类型数据在 Column 中有不同的组织方式，这使得他们有如下的特点：\n\n1.  定长类型的 Column 可以随机读写任意元素；\n\n2.  变长类型的 Column 可以随机读，但更改中间某元素后，可能需要移动该元素后续所有元素，导致随机写性能很差。\n\n对于定长类型（如 `int64`），我们在计算时会将其转成 Golang Slice（如 `[]int64`），然后直接读写这个 Slice。相比于调用 Column 的接口，需要的 CPU 指令更少，性能更好。同时，转换后的 Slice 仍然引用着 Column 中的内存，修改后不用将数据从 Slice 拷贝到 Column 中，开销降到了最低。\n\n对于变长类型，元素长度不固定，且为了保证元素在内存中连续存放，所以不能直接用 Slice 的方式随机读写。我们规定变长类型数据以追加写（`append`）的方式更新，用 Column 的 `Get()` 接口进行读取。\n\n总的来说，变长和定长类型的读写方式如下：\n\n1. 定长类型（以 `int64` 为例)\n\n    a. `ResizeInt64s(size, isNull)`：预分配 size 个元素的空间，并把所有位置的 `null` 标记都设置为 `isNull`；\n    \n    b.  `Int64s()`：返回一个 `[]int64` 的 Slice，用于直接读写数据；\n    \n    c.  `SetNull(rowID, isNull)`：标记第 `rowID` 行为 `isNull`。\n\n2. 变长类型（以 `string` 为例）\n    \n    a. `ReserveString(size)`：预估 size 个元素的空间，并预先分配内存；\n    \n    b. `AppendString(string)`: 追加一个 string 到向量末尾；\n    \n    c.  `AppendNull()`：追加一个 `null` 到向量末尾；\n    \n    d.  `GetString(rowID)`：读取下标为 `rowID` 的 string 数据。\n\n当然还有些其他的方法如 `IsNull(rowID)`，`MergeNulls(cols)` 等，就交给大家自己去探索了，后面会有这些方法的使用例子。\n\n### 2. 表达式向量化计算框架\n\n向量化的计算接口大概如下（[完整的定义在这里](https://github.com/pingcap/tidb/blob/master/expression/builtin.go#L340)）：\n\n```\nvectorized() bool\nvecEvalXType(input *Chunk, result *Column) error\n```\n\n*   `XType` 可能表示 `Int`, `String` 等，不同的函数需要实现不同的接口；\n\n*   `input` 表示输入数据，类型为 `*Chunk`；\n\n*   `result` 用来存放结果数据。\n\n外部执行算子（如 Projection，Selection 等算子），在调用表达式接口进行计算前，会通过 `vectorized()` 来判断此表达式是否支持向量化计算，如果支持，则调用向量化接口，否则就走行式接口。\n\n对于任意表达式，只有当其中所有函数都支持向量化后，才认为这个表达式是支持向量化的。\n\n比如 `(2+6)*3`，只有当 `MultiplyInt` 和 `PlusInt` 函数都向量化后，它才能被向量化执行。\n\n## 为函数实现向量化接口\n\n要实现函数向量化，还需要为其实现 `vecEvalXType()` 和 `vectorized()` 接口。\n\n* 在 `vectorized()` 接口中返回 `true` ，表示该函数已经实现向量化计算；\n\n* 在 `vecEvalXType()` 实现此函数的计算逻辑。\n\n**尚未向量化的函数在 [issue/12058](https://github.com/pingcap/tidb/issues/12058) 中，欢迎感兴趣的同学加入我们一起完成这项宏大的工程。**\n\n向量化代码需放到以 `_vec.go` 结尾的文件中，如果还没有这样的文件，欢迎新建一个，注意在文件头部加上 licence 说明。\n\n这里是一个简单的例子 [PR/12012](https://github.com/pingcap/tidb/pull/12012)，以 `builtinLog10Sig` 为例：\n\n1.  这个函数在 `expression/builtin_math.go` 文件中，则向量化实现需放到文件 `expression/builtin_math_vec.go` 中；\n\n2.  `builtinLog10Sig` 原始的非向量化计算接口为 `evalReal()`，那么我们需要为其实现对应的向量化接口为 `vecEvalReal()`；\n\n3.  实现完成后请根据后续的说明添加测试。\n\n下面为大家介绍在实现向量化计算过程中需要注意的问题。\n\n### 1. 如何获取和释放中间结果向量\n\n存储表达式计算中间结果的向量可通过表达式内部对象 `bufAllocator` 的 `get()` 和 `put()` 来获取和释放，参考 [PR/12014](https://github.com/pingcap/tidb/pull/12014)，以 `builtinRepeatSig` 的向量化实现为例：\n\n```\nbuf2, err := b.bufAllocator.get(types.ETInt, n)\nif err != nil {\n    return err\n}\ndefer b.bufAllocator.put(buf2) // 注意释放之前申请的内存\n```\n\n### 2. 如何更新定长类型的结果\n\n如前文所说，我们需要使用 `ResizeXType()` 和 `XTypes()` 来初始化和获取用于存储定长类型数据的 Golang Slice，直接读写这个 Slice 来完成数据操作，另外也可以使用 `SetNull()` 来设置某个元素为 `NULL`。代码参考 [PR/12012](https://github.com/pingcap/tidb/pull/12012)，以 `builtinLog10Sig` 的向量化实现为例：\n\n```\nf64s := result.Float64s()\nfor i := 0; i < n; i++ {\n    if isNull {\n        result.SetNull(i, true)\n    } else {\n        f64s[i] = math.Log10(f64s[i])\n    }\n}\n```\n\n### 3. 如何更新变长类型的结果\n\n如前文所说，我们需要使用 `ReserveXType()` 来为变长类型预分配一段内存（降低 Golang runtime.growslice() 的开销），使用 `AppendXType()` 来追加一个变长类型的元素，使用 `GetXType()` 来读取一个变长类型的元素。代码参考 [PR/12014](https://github.com/pingcap/tidb/pull/12014)，以 `builtinRepeatSig` 的向量化实现为例：\n\n```\nresult.ReserveString(n)\n...\nfor i := 0; i < n; i++ {\n    str := buf.GetString(i)\n    if isNull {\n        result.AppendNull()\n    } else {\n    result.AppendString(strings.Repeat(str, int(num)))\n    }\n}\n```\n\n### 4. 如何处理 Error\n\n所有受 SQL Mode 控制的 Error，都利用对应的错误处理函数在函数内就地处理。部分 Error 可能会被转换成 Warn 而不需要立即抛出。\n\n这个比较杂，需要查看对应的非向量化接口了解具体行为。代码参考 [PR/12042](https://github.com/pingcap/tidb/pull/12042)，以 `builtinCastIntAsDurationSig` 的向量化实现为例：\n\n```\nfor i := 0; i < n; i++ {\n    ...\n    dur, err := types.NumberToDuration(i64s[i], int8(b.tp.Decimal))\n    if err != nil {\n       if types.ErrOverflow.Equal(err) {\n          err = b.ctx.GetSessionVars().StmtCtx.HandleOverflow(err, err) // 就地利用对应处理函数处理错误\n       }\n       if err != nil { // 如果处理不掉就抛出\n          return err\n       }\n       result.SetNull(i, true)\n       continue\n    }\n    ...\n}\n```\n\n### 5. 如何添加测试\n\n我们做了一个简易的测试框架，可避免大家测试时做一些重复工作。\n\n该测试框架的代码在 `expression/bench_test.go` 文件中，被实现在 `testVectorizedBuiltinFunc` 和 `benchmarkVectorizedBuiltinFunc` 两个函数中。\n\n我们为每一个 `builtin_XX_vec.go` 文件增加了 `builtin_XX_vec_test.go` 测试文件。当我们为一个函数实现向量化后，需要在对应测试文件内的 `vecBuiltinXXCases` 变量中，增加一个或多个测试 case。下面我们为 log10 添加一个测试 case：\n\n```\nvar vecBuiltinMathCases = map[string][]vecExprBenchCase {\n    ast.Log10: {\n        {types.ETReal, []types.EvalType{types.ETReal}, nil},\n    },\n}\n```\n\n具体来说，上面结构体中的三个字段分别表示:\n\n1.  该函数的返回值类型；\n\n2.  该函数所有参数的类型；\n\n3.  是否使用自定义的数据生成方法（dataGener），`nil` 表示使用默认的随机生成方法。\n\n对于某些复杂的函数，你可自己实现 dataGener 来生成数据。目前我们已经实现了几个简单的 dataGener，代码在 `expression/bench_test.go` 中，可直接使用。\n\n添加好 case 后，在 expression 目录下运行测试指令：\n\n```\n# 功能测试\nGO111MODULE=on go test -check.f TestVectorizedBuiltinMathFunc\n\n# 性能测试\ngo test -v -benchmem -bench=BenchmarkVectorizedBuiltinMathFunc -run=BenchmarkVectorizedBuiltinMathFunc\n```\n\n在你的 PR Description 中，请把性能测试结果附上。不同配置的机器，性能测试结果可能不同，我们对机器配置无任何要求，你只需在 PR 中带上你本地机器的测试结果，让我们对向量化前后的性能有一个对比即可。\n\n## 如何成为 Contributor\n\n**为了推进表达式向量化计算，我们正式成立 Vectorized Expression Working Group，其具体的目标和制度详见[这里](https://github.com/pingcap/community/blob/master/working-groups/wg-vec-expr.md)。与此对应，我们在 [TiDB Community Slack](https://pingcap.com/tidbslack/) 中创建了 [wg-vec-expr channel](https://app.slack.com/client/TH91JCS4W/CMRD79DRR) 供大家交流讨论，不设门槛，欢迎感兴趣的同学加入。**\n\n如何成为 Contributor：\n\n1.  在此 [issue](https://github.com/pingcap/tidb/issues/12058) 内选择感兴趣的函数并告诉大家你会完成它；\n\n2.  为该函数实现 `vecEvalXType()` 和 `vectorized()` 的方法；\n\n3.  在向量化测试框架内添加对该函数的测试；\n\n4.  运行 `make dev`，保证所有 test 都能通过；\n\n5.  发起 Pull Request 并完成 merge 到主分支。\n\n如果贡献突出，可能被提名为 reviewer，reviewer 的介绍请看 [这里](https://github.com/pingcap/community/blob/master/CONTRIBUTING.md#reviewer)。\n\n如果你有任何疑问，也欢迎到 wg-vec-expr channel 中提问和讨论。  \n> 点击查看更多 [成为 Contributor 系列文章](https://pingcap.com/zh/blog/?tag=Contributor)\n","date":"2019-09-16","author":"Yuanjia Zhang","fillInMethod":"writeDirectly","customUrl":"10mins-become-contributor-of-tidb-20190916","file":null,"relatedBlogs":[]},{"id":"Blogs_72","title":"从使用者到开发者，知乎参与 TiDB 社区背后的故事","tags":["社区"],"category":{"name":"社区动态"},"summary":"“从前我们更多是站在使用者的角度从开源社区汲取养分，随着知乎技术架构和内部工程能力的成长，未来我们希望能够以更加积极主动的状态参与开源项目，回馈社区。”","body":">**作者介绍**：孙晓光，知乎技术平台团队负责人，负责建设知乎在线和离线的基础设施平台，为业务开发提供统一的基础设施。曾多年从事私有云相关产品开发工作，关注云原生技术，TiKV 项目 Committer。\n\n关注 TiDB 的朋友们可能发现继 Follower Read 在 TiKV 端的 PR 合并后，TiDB 端相关的 PR 也于近期完成了到主干的合并工作。如果后期的稳定性测试一切正常，相关功能应该会随 TiDB 3.1 发布。Follower Read 功能本身从代码量上看并不大，但这个功能的意义尤其是对互联网类型业务来说是非常大的。\n\n前段时间 PingCAP CTO 黄东旭已经写了 [一篇文章](https://pingcap.com/blog-cn/follower-read-the-new-features-of-tidb/)，从原理角度对 Follower Read 做了非常透彻的介绍和分析。今天我想从非技术的角度介绍 Follower Read 功能的落地过程，并从 Contributor 的视角跟大家聊一聊个人参与 TiDB 开发过程中的体验和感受。最后站在知乎技术平台团队的角度，聊一下我们未来在积极参与开源项目，共同建设社区的愿望和决心。\n\n\n## Follower Read 背后的故事\n\n\nFollower Read 的实现思路在 PingCAP 工程师大脑里应该已经存在很久了，但出于各种原因这个特性的优先级一直不够高，并没有能排到开发计划中。年中的时候我们开始尝试在知乎更广泛的业务中引入 TiDB，在灰度过程中我们遇到了某些特定工作负载下 TiDB 表现不够理想的问题。目前看来 TiDB 读写操作都交给 Leader 完成，是我们目前在特定负载下遇到吞吐问题的瓶颈点。\n\n在理清思路后，我们同 PingCAP 的工程师做了几次交流并达成一致，决定通过 Follower Read 的方式来解决我们业务场景中极端热点数据访问的吞吐问题。在实际需求的驱动下， PingCAP 同学将 Follower Read 相关特性的优先级提高，快速确定了相关功能的技术方案并启动了 TiKV 端的开发工作。作为 Follower Read 功能的需求方，知乎负责这个需求在 TiDB 上的落地工作。\n\nPingCAP 工程师用了大约两周的时间完成了 [TiKV 层 Follower Read 整个功能的开发测试](https://github.com/tikv/tikv/pull/5051)，并将其合并到 master 分支中，随后我们开始了 [TiDB 侧相应功能的开发](https://github.com/pingcap/tidb/pull/11347)，在 PingCAP 小伙伴们的帮助下最终完成了相应功能到 master 分支的合并。作为知乎和 PingCAP 两家公司第一次联合开发的成果，这个功能的落地对双方都有着重大的意义。\n\n## 从 Contributor 到 Committer\n\n在以知乎技术平台团队成员的身份参与 TiDB 贡献之前，个人曾经在过去的一年里以用户的身份为 TiKV & TiDB 做过一些小型的贡献。接下来我就从个人角度聊一下从 Contributor 到 Committer 的成长过程和其中的体验。\n\n第一次为 PingCAP 旗下项目提交 PR 并成为 Contributor 发生在大约一年前，我在为内部开发的业务系统选择合适的存储后端时，尝试给 TiKV 增加了一些批量操作接口。PR 提出后，PingCAP 首席架构师唐刘很快就跟我建立了联系，在随后的交流中帮助我快速完善 PR 并最终合并到 TiKV 的主干中。\n\n虽然以往以零散的方式给很多开源项目提交过 Patch，但这次的体验是完全不同的，PingCAP 和社区伙伴们热心的帮助和鼓励让我切身感受到了活跃的开源社区所具有的独特魅力。随后出于个人兴趣，我在 TiDB 相关的项目中又陆陆续续做了一些简单的贡献，最终得到大家的认可成为 TiKV 项目的 Committer 之一。\n\n## 拥抱开源\n\n回过头来看这段时间的成长和收获都是巨大的，不但学习到了如何同开源社区众多优秀的贡献者更加高效的交流，并且对开源的价值理念和开源在基础软件领域的重大意义有了更加深入的理解。\n\n近期随着在公司所在团队的转换，我个人开始更多的关注在线和离线的基础设施在知乎的演进。知乎一直以来都鼓励拥抱开源，并基于大量开源组件搭建了知乎的技术架构，得益于开源的力量，知乎的内部平台一直都紧随着行业技术发展的潮流。从前我们更多是站在使用者的角度从开源社区汲取养分，随着知乎技术架构和内部工程能力的成长，未来我们希望能够以更加积极主动的状态参与开源项目，回馈社区。Follower Read 是知乎第一次以 Contributor 身份参与 TiDB 社区建设，未来我们会参与更多的技术社区的建设为开源社区的发展贡献我们的力量。","date":"2019-09-12","author":"孙晓光","fillInMethod":"writeDirectly","customUrl":"zhihu-the-story-of-contributing-to-tidb-community","file":null,"relatedBlogs":[]},{"id":"Blogs_175","title":"三十分钟成为 Contributor | 提升 TiDB Parser 对 MySQL 8.0 语法的兼容性","tags":["TiDB","社区","Contributor"],"category":{"name":"社区动态"},"summary":"本次活动聚焦于语法兼容，提升 TiDB SQL Parser 对 MySQL 8.0 的语法支持。对于新的贡献者而言，除了能将理论知识运用到实践上以外，还可以从中体验参与一个开源项目的整体流程与规范。","body":"TiDB 的一大特性就是和 MySQL 高度兼容，目标是让用户能够无需修改代码即可从 MySQL 迁移至 TiDB。要达成这个目标，需要完成两个提升兼容性的任务，分别是「语法兼容」和「功能行为兼容」。\n\n**本次活动聚焦于语法兼容，提升 TiDB SQL Parser 对 MySQL 8.0 的语法支持。对于新的贡献者而言，除了能将理论知识运用到实践上以外，还可以从中体验参与一个开源项目的整体流程与规范。**\n\n我们把 TiDB Parser 整体看作一个函数，输入是 SQL 字符串，输出是用于描述 SQL 语句的抽象语法树（AST）。在这个转换的过程中涉及到的组件有两个：一个是 lexer，负责将字符流变成 Token，并赋予它们类别标识，这个过程叫「Tokenize」；另一个是 parser，负责将 Token 转为树状结构，便于将来遍历和转换，这个过程叫「Parse」；TiDB 使用了 parser 生成工具 goyacc，它能够根据 `parser.y` 生成 `parser.go`，其中包含了名称为 `Parse` 的函数接口，供 TiDB 直接使用。更多关于 TiDB Parser 以及 Lex & Yacc 的信息请参考 [TiDB SQL Parser 的实现](https://pingcap.com/blog-cn/tidb-source-code-reading-5/)。\n\n## 参与流程\n\n参与流程分为 7 步：**领任务  -> 写 test case -> make test -> coding -> 补充 test case -> make test -> 提 PR**。\n\n### 1. 从 Issue 领取任务\n\n我们会在 [Improve parser compatibility](https://github.com/pingcap/tidb/issues/11486) 周期性发布不兼容的 Bad SQL Case 组，每组 Case 都会构成一个 Issue，Contributor 选择某个 Issue，在它的下方评论：**Let me fix it**。在我们将 Contributor 的 Github ID 添加到 Index Issue 中后，即完成任务的领取。\n\n### 2. 编写测试用例\n\n根据 Issue 描述的情况在 [`parser_test.go`](https://github.com/pingcap/parser/blob/master/parser_test.go) 中编写测试用例，除了 Issue 中提到的 Case 以外，可以适当添加更多的 Case。保证目标 SQL Case 语句能够通过 Parser 解析，并且通过 Restore 还原为预期的 SQL。\n\n### 3. 执行所有测试\n\nparser 根目录下运行 `make test`，确保第一次测试失败，并且失败的 Case 是第 2 步编写的。\n\n### 4. 编码\n\nContributor 修改文法规则。对于涉及到语义层面的规则变动，需要同步修改 AST 节点的数据结构（AST 节点定义在 `parser/ast` 中）。TiDB 通过 AST 树生成执行计划，修改 AST 节点可能会影响 TiDB 的行为，因此应尽量保持原有结构，不改变原有的属性，如果确实有修改 AST 树必要，我们会帮助 Contributor 检查 TiDB 的行为是否正常。另外，AST 节点其中的两个接口方法是 `Accept` 和 `Restore`，分别用于遍历子树和通过 AST 树还原 SQL 字符串。应确保它们的行为都符合预期。\n\n另外，还要检查新加的规则是否存在冲突问题。「冲突」可以被理解为当 parser 读到某个 token 时，有两种或以上的方式来构造语法树，从而导致歧义。goyacc 所生成的 parser 采用了 `LALR(1)` 方法进行解析，冲突有两类：一类是两条规则都能被用于归约，称为 `reduce-reduce` 冲突。另一类是既能使用一条规则归约，又能按照另一条规则移进下一个 token，称为 `shift-reduce` 冲突。可以通过指定优先级的方式消除冲突，具体可以参考 yacc 的 [%precedence 和 %prec 指示](https://www.gnu.org/software/bison/manual/html_node/Precedence.html#Precedence)。\n\n编码完成后在项目根目录下运行 `make parser`，这时会执行 goyacc 重新生成 `parser.go` 文件。\n\n### 5. 补充 test case\n\n根据实际情况尽可能提升测试覆盖率。\n\n### 6. 执行所有测试\n\nparser 根目录下运行 `make test`，确保测试通过。\n\n### 7. 提交 PR\n\t\n提交 PR 之前请先阅读 [contributing 指南](https://github.com/pingcap/tidb/blob/master/CONTRIBUTING.md)。下面是 PR 的模板，逐项填写即可。\n\n```\t\n### What problem does this PR solve?\n\n#### [ Put the subtask title here ]\n\nIssue: [ put the subtask issue link here ]\n\n#### MySQL Syntax:\n\n[ describe MySQL syntax here ]\n\n#### Bad SQL Case:\n\n[ give a SQL statement example that passes MySQL but fails TiDB parser ]\n\n[ give a SQL statement example that passes MySQL but fails TiDB parser ]\n\t\n...\n\t\n### Check List\n\t\nTests\n\n- Unit test\n```\n\n## 示例\n\n**下面以添加 「REMOVE PARTITIONING」 语法支持为例解释说明整个过程**。\n\n### 1. 从 Issue 领取任务\n\n从 [这里](https://github.com/pingcap/tidb/issues/11486) 找到 `REMOVE PARTITIONING` 子任务。[子任务 Issue](https://github.com/pingcap/parser/issues/402) 中有若干不兼容的 Case。\n\n首先，手动测试任一 Case，发现在 MySQL 下输出：\n\n```\nError 1505: Partition management on a not partitioned table is not possible\n```\n\n而在 TiDB 下输出：\n\n```\nError 1064: You have an error in your SQL syntax; check the manual that corresponds to your TiDB version for the right syntax to use line 1 column 20 near \"remove partitioning\"\n```\n\n这意味着 parser 无法识别 remove 关键字。\n\n确认了问题存在后，到 [该 Issue](https://github.com/pingcap/parser/issues/402) 下评论：**Let me fix it**，完成任务领取。\n\n### 2. 编写测试用例\n\n在 `parser_test.go` 下寻找合适位置添加测试用例，这里我们选择在 `func (s *testParserSuite) TestDDL(c *C)` 的 [末尾](https://github.com/pingcap/parser/pull/396/files#diff-688912c3f38a8a80d6bdc16c02088d69R2172) 添加：\n\n```\n// for remove partitioning\n{\"alter table t remove partitioning\", true, \"ALTER TABLE `t` REMOVE PARTITIONING\"},\n{\"alter table db.ident remove partitioning\", true, \"ALTER TABLE `db`.`ident` REMOVE PARTITIONING\"},\n{\"alter table t lock = default remove partitioning\", true, \"ALTER TABLE `t` LOCK = DEFAULT REMOVE PARTITIONING\"},\n```\n\n这里每一个 test case 分成了三部分，第一列是用于测试的 SQL 语句，第二列是「是否期望第一列的语句 parse 通过」，第三列是「从语法树 restore 后期望的 SQL 语句」。具体可以参考 [`TestDDL.RunTest()`](https://github.com/pingcap/parser/blob/53c769c5836485c83d5f339faab97ef5d853d560/parser_test.go#L308)。\n\n### 3. 执行所有测试\n\nparser 根目录下运行 `make test`，确保第一次测试失败，并且 fail 的 case 是第 2 步编写的。\n\n```\nFAIL: parser_test.go:1664: testParserSuite.TestDDL\n\nparser_test.go:2148:\n    s.RunTest(c, table)\nparser_test.go:318:\n    c.Assert(err, IsNil, comment)\n... value *errors.withStack = line 1 column 20 near \"remove partitioning\"  (\"line 1 column 20 near \\\"remove partitioning\\\" \")\n... source alter table t remove partitioning\n```\n\n错误信息和期望的一致，则可以开始进行下一步。\n\n### 4. 编码\n\n#### 4.1 修改 `parser.y` 文件\n\n首先从 [MySQL 文法](https://github.com/mysql/mysql-server/blob/8.0/sql/sql_yacc.yy) 中找到 remove partitioning 的定义：\n\n```\nalter_table_stmt: ALTER TABLE_SYM table_ident opt_alter_table_actions\n| ALTER TABLE_SYM table_ident standalone_alter_table_action\n\nopt_alter_table_actions: opt_alter_command_list\n| opt_alter_command_list alter_table_partition_options\n\nalter_table_partition_options: partition_clause\n| REMOVE_SYM PARTITIONING_SYM\n```\n\n经过分析可得该语法只能出现在 SQL 语句的最后一个部分，并且只能出现一次。\n\n在 `parser.y` 中找到 `AlterTableStmt`，其中一条规则是：\n\n```\n\"ALTER\" IgnoreOptional \"TABLE\" TableName AlterTableSpecListOpt PartitionOpt\n```\n\n其中最后一个符号 PartitionOpt 和 MySQL 中 `partition_clause` 非常相似，为了支持 remove partitioning，容易想到引入一条规则：\n\n```\nAlterTablePartitionOpt: PartitionOpt | \"REMOVE\" \"PARTITIONING\"\n```\n\n将 `PartitionOpt` 的语义动作移到 `AlterTablePartitionOpt` 中，`REMOVE PARTITIONING` 部分先返回 `nil`，并添加 parser 警告，表示目前 parser 能够解析但 TiDB 尚未支持该功能。修改后的规则如下：\n\n```\nAlterTablePartitionOpt:\n\tPartitionOpt\n\t{\n\t\tif $1 != nil {\n\t\t\t$$ = &ast.AlterTableSpec{\n\t\t\t\tTp: ast.AlterTablePartition,\n\t\t\t\tPartition: $1.(*ast.PartitionOptions),\n\t\t\t}\n\t\t} else {\n\t\t\t$$ = nil\n\t\t}\n\t}\n|\t\"REMOVE\" \"PARTITIONING\"\n\t{\n\t\t$$ = nil\n\t\tyylex.AppendError(yylex.Errorf(\"The REMOVE PARTITIONING clause is parsed but ignored by all storage engines.\"))\n\t\tparser.lastErrorAsWarn()\n\t}\n```\n\n由于 `REMOVE` 和 `PARTITIONING` 都是新添加的关键字，如果不做任何处理，lexer 扫描的时候只会将它们看作普通的标识符。于是需要在 `parser.y` 的 `%token` 字段上补充声明，其中一个目的是为该字符串产生一个 `tokenID`（一个整数），供 lexer 标识。另外 `goyacc` 也会对 `parser.y` 中所有的字符串常量进行检查，如果没有相应的 `token` 声明，会报 `Undefined symbol` 的错误。\n\n为支持这两个关键字，我们在文件开头的 `token` 字段添加声明。由于 `REMOVE` 和 `PARTITIONING` 都是非保留关键字，它们应被添加在含有 `The following tokens belong to UnReservedKeyword` [注释](https://github.com/pingcap/parser/blob/53c769c5836485c83d5f339faab97ef5d853d560/parser.y#L274) 的下方。此外，非保留字说明它们能够作为标识符 `Identifier`，因此在 `Identifier` 规则下的 [`UnRerservedKeyword`](https://github.com/pingcap/parser/blob/53c769c5836485c83d5f339faab97ef5d853d560/parser.y#L3717) 中也应加上 `REMOVE` 和 `PARTITIONING`。\n\n关于如何确定一个关键字是保留的还是非保留的，可以参考 [MySQL 文档](https://dev.mysql.com/doc/refman/8.0/en/keywords.html)。\n\n#### 4.2 增加「关键字-`tokenID`」映射\n\n前文提到，添加声明是为了让 lexer 能够识别关键字并赋予对应的 `tokenID`，对于 lexer 而言，它需要一个从关键字字符串到 `tokenID` 的映射关系。在 TiDB parser 中，这个映射关系就是 [`misc.go`](https://github.com/pingcap/parser/blob/53c769c5836485c83d5f339faab97ef5d853d560/misc.go) 中的 `tokenMap` 结构。\n\n在这个例子中，我们往 `tokenMap` 中添加 `remove` 和 `partitioning`（如果不添加，会使关键字一致性的检查测试失败）。\n\n#### 4.3 修改 AST 节点\n\n到目前为止，我们已经让 `goyacc` 生成的 parser 能够解析 remove partitioning 语法。但是，解析完成后并没有返回有效的数据结构（4.1 中我们返回了 `nil`），这意味着 parser 不能够根据语法树重新生成原 SQL 语句。\n\n所以，要修改现有的 AST 节点，使它们能够以某种形式保存 remove partitioning 信息。回顾目前规则层面的修改：\n\n```\nAlterTableStmt:\n\"ALTER\" IgnoreOptional \"TABLE\" TableName AlterTableSpecListOpt PartitionOpt\n```\n\n已改为：\n\n```\nAlterTableStmt:\n\"ALTER\" IgnoreOptional \"TABLE\" TableName AlterTableSpecListOpt AlterTablePartitionOpt\nAlterTablePartitionOpt:\n      PartitionOpt | \"REMOVE\" \"PARTITIONING\"\n```\n\n其中几个非终结符对应的数据结构如下：\n\n```\nAlterTableSpecListOpt -> []AlterTableSpec\nPartitionOpt -> PartitionOptions\n```\n\n关于修改节点，有几种方案可以选择：\n\n1. 增加一个新的节点 struct，表示 `AlterTablePartitionOpt`。其中包含 `PartitionOptions` 和一个 bool 值，表示是否为 remove partitioning。\n\n2. 将 remove partitioning 看作 `PartitionOptions`，在内部添加一个 bool 成员 `isRemovePartitioning` 以做区分。\n\n3. 将 `PartitionOpt` 和 remove partitioning 都看作 `AlterTableSpec`，为 `AlterTableSpec` 的添加一个类型，单独表示 remove partitioning。\n\n经过比较和分析，我们发现第一个方案会引入新的数据结构，有较大的概率会引起现有的 TiDB 测试不过，为此可能要修改 TiDB 方面的代码，工作量大的同时提高了 parser 的复杂度，因此作为备选方案；第二个方案没有引入新的数据结构，但是修改了现有的数据结构（加了个 bool 成员）；第三个方案即没有添加也没有修改数据结构，并且能够以较少的代码完成任务，作为首选方案。\n\n**在以上的选择中，我们遵循「尽量不修改 AST 节点结构」的原则。**\n\n按照方案三，观察 [`AlterTableSpec`](https://github.com/pingcap/parser/pull/396/files#diff-688d51c34d61e5d538b15582305c9a8dL1768)，其定义如下：\n\n```\ntype AlterTableSpec struct {\n  node\n  ...\n  Tp              AlterTableType\n  Name            string\n  ...\n}\n```\n\n其中一个成员是 `Tp`，它所属的类型包含了 `AlterTable` 的许多操作，例如 `AddColumn`，`AddConstraint`，`DropColumn` 等。我们的任务是添加一个 [类似的 Type](https://github.com/pingcap/parser/pull/396/files#diff-688d51c34d61e5d538b15582305c9a8dR1708)，让它能够表示 remove partitioning。\n\n到这里，解析完 SQL 语句生成的 AST 树已经包含 remove partitioning 的信息了。接下来要处理 Restore，让它能够从 AST 树还原出 SQL 语句。`AlterTableSpec` 的 Restore 十分简单，加一个 case 即可，这里不再赘述。\n\n#### 4.4 完善 `parser.y`\n\n第一次修改 `parser.y` 的时候我们在新加规则的语义动作中返回了 `nil`，原因是尚未确定 AST 是否需要修改，以及如何修改。而到这一步，这些都已经确定下来了，把 remove partitioning 看作 `AlterTableSpec` 类型：\n\n```\n|       \"REMOVE\" \"PARTITIONING\"\n      {\n              $$ = &ast.AlterTableSpec{\n                     Tp: ast.AlterTableRemovePartitioning,\n              }\n             yylex.AppendError(yylex.Errorf(\"The REMOVE PARTITIONING clause is parsed but ignored by all storage engines.\"))\n             parser.lastErrorAsWarn()\n      }\n```\n\n注意，这里必须抛出警告，表示虽然目前 parser 能够解析该语法，但实际上 TiDB 并未支持相应的功能。\n\n#### 5. 补充 test case\n\n这里，所有的代码修改引入的分支结构都能够被现有的测试覆盖，因此在提升覆盖率上没有需求。当然，如果想要测试更多类似的 case，可以将它们添加到前面提到的 `TestDDL` 函数中。\n\n#### 6. 执行所有测试（`make test`）\n\n```\ngofmt (simplify)\nsh test.sh\nok      github.com/pingcap/parser       4.294s  coverage: 62.1% of statements in ./...\nok      github.com/pingcap/parser/ast   2.090s  coverage: 42.3% of statements in ./...\nok      github.com/pingcap/parser/auth  1.155s  coverage: 1.3% of statements in ./... [no tests to run]\nok      github.com/pingcap/parser/charset       1.094s  coverage: 2.0% of statements in ./...\nok      github.com/pingcap/parser/format        1.114s  coverage: 2.5% of statements in ./...\n?       github.com/pingcap/parser/goyacc        [no test files]\nok      github.com/pingcap/parser/model 1.100s  coverage: 3.5% of statements in ./...\nok      github.com/pingcap/parser/mysql 1.102s  coverage: 1.3% of statements in ./... [no tests to run]\nok      github.com/pingcap/parser/opcode        1.099s  coverage: 1.4% of statements in ./...\nok      github.com/pingcap/parser/terror        1.091s  coverage: 2.3% of statements in ./...\nok      github.com/pingcap/parser/types 1.106s  coverage: 7.0% of statements in ./...\n\n```\n\n**确保所有的 test 都是 ok 的状态。**\n\n#### 7. 提交 PR\n\n按照 PR 模板逐项填写。\n\n```\n### What problem does this PR solve?\n\n#### Fix compatibility problem about keyword REMOVE PARTITIONING\n\nIssue: pingcap/parser#402\n\n#### MySQL Syntax:\n\nalter_specification:\n...\n  | REMOVE PARTITIONING\n\n### Bad SQL Case:\n\nalter table t remove partitioning;\nalter table t lock = default, remove partitioning;\nalter table t drop check c, remove partitioning;\n\n### Check List\n\nTests\n- Unit test\n\n```\n\n**需要特别指出的是，我们鼓励各位 Contributor 多使用 `make test`。当不知道从何处入手或者失去目标时，`make test` 输出的错误信息或许能够引导大家进行思考和探索**。\n\n>Tips: [完整的 PR 示例](https://github.com/pingcap/parser/pull/396)\n\n## FAQ\n\n以下是在增加 remove partitioning 语法支持时遇到的问题和解决方法。\n\n**Q1. 为什么不在 `PartitionOpt` 中直接添加规则？** \n\n**A1**：`PartitionOpt` 用于匹配含有 `partition by` 的 SQL 语句，除了 `Alter Table` 语句以外，它还被 `Create Table` 使用，而 `remove partitioning` 只存在于 `alter table` 语句中，因此不能在 `PartitionOpt` 中添加规则。\n\n**Q2. 执行 make test 时报错：** \n\n```\nparser.y:1100:1: undefined symbol \"PARTITIONING\"\nparser.y:1100:1: undefined symbol \"REMOVE\"\nmake[1]: *** [Makefile:19: parser] Error 1\n```\n\n**A2**：在 yacc 中，出现在规则中的字符串，要么是 `token`（终结符），要么是非终结符。这里引用一段 yacc 的规范：\n\n```\nNames refer to either tokens or nonterminal symbols.\nNames representing tokens must be declared; this is most simply done by writing\n%token   name1 name2 . . .\n```\n\n所以，修复方法是在 `parser.y` 的 `%token` 字段上添加 `PARTITIONING` 和 `REMOVE` 的声明。\n\n**Q3. 执行 make test 时报错：** \n\n```\n c.Assert(len(tokenMap)-len(aliases), Equals, keywordCount-len(windowFuncTokenMap))\n... obtained int = 454\n... expected int = 456\n```\n\n**A3**：这是关键字的一致性检查出了问题，解决方案是补充 `tokenMap`（它是关键字到 `token ID` 的映射，被 scanner 用来判断某个字符串是否为关键字）。\n\n**Q4. 执行 make test 时报错：** \n\n```\nFAIL: parser_test.go:1666: testParserSuite.TestDDL\nparser_test.go:2166:\n    s.RunTest(c, table)\nparser_test.go:351:\n    c.Assert(restoreSQLs, Equals, expectSQLs, comment)\n... obtained string = \"ALTER TABLE `t`\"\n... expected string = \"ALTER TABLE `t` REMOVE PARTITIONING\"\n... restore ALTER TABLE `t`; expect ALTER TABLE `t` REMOVE PARTITIONING\n```\n\n**A4**：这个错误说明 parser 已经解析通过，但不能从语法树中恢复原 SQL 语句的 remove partitioning 部分。此时应检查相应 AST 节点的 Restore 方法是否正确处理了 `REMOVE PARTITIONING`。\n\n***最后欢迎大家加入 [TiDB Contributor Club](https://pingcap.com/community-cn/)，无门槛参与开源项目，改变世界从这里开始吧！***  \n> 点击查看更多 [成为 Contributor 系列文章](https://pingcap.com/zh/blog/?tag=Contributor)","date":"2019-08-08","author":"谢腾进 赵一霖","fillInMethod":"writeDirectly","customUrl":"30mins-become-contributor-of-tidb-20190808","file":null,"relatedBlogs":[]},{"id":"Blogs_119","title":"写给社区的回顾和展望：TiDB 2019, Level Up!","tags":["TiDB","TiKV","社区","社区动态"],"category":{"name":"社区动态"},"summary":"2018 年对于 TiDB 和 PingCAP 来说是一个由少年向成年的转换的一年，如果用一个关键字来概括就是「蜕变」。","body":"**2018 年对于 TiDB 和 PingCAP 来说是一个由少年向成年的转换的一年，如果用一个关键字来概括就是「蜕变」**。在这一年很欣喜的看到 TiDB 和 TiKV 在越来越多的用户使用在了越来越广泛的场景中，作为一个刚刚 3 岁多的开源项目，没有背后强大的社区的话，是没有办法取得这样的进展的。\n同时在技术上，2018 年我觉得也交出了一份令人满意的答卷，TiDB 的几个主要项目今年一共合并了 4380 个提交，这几天在整理 2018 年的 Change Log 时候，对比了一下年初的版本，这 4380 个 Commits 背后代表了什么，这里简单写一个文章总结一下。\n\n回想起来，TiDB 是最早定位为 HTAP 的通用分布式数据库之一，如果熟悉我们的老朋友一定知道，我们最早时候一直都是定位 NewSQL，当然现在也是。但是 NewSQL 这个词有个问题，到底 New 在哪，解决了哪些问题，很难一目了然，其实一开始我们就想解决一个 MySQL 分库分表的问题，但是后来慢慢随着我们的用户越来越多，使用的场景也越来越清晰，很多用户的场景已经开始超出了一个「更大的 MySQL 」的使用范围，于是我们从实验室和学术界找到了我们觉得更加清晰的定义：HTAP，希望能构建一个融合 OLTP 和 OLAP 通用型分布式数据库。但是要达成这个目标非常复杂，我们的判断是如果不是从最底层重新设计，很难达到我们的目标，**我们认为这是一条更困难但是正确的路，现在看来，这条路是走对了，而且未来会越走越快，越走越稳。**\n\n\n在 SQL 层这边，TiDB 选择了 MySQL 的协议兼容，一方面持续的加强语法兼容性，另一方面选择自研优化器和执行器，带来的好处就是没有任何历史负担持续优化。回顾今年最大的一个工作应该是重构了执行器框架，TiDB的 SQL 层还是经典的 Volcano 模型，我们引入了新的内存数据结构 Chunk 来批量处理多行数据，并对各个算子都实现了基于 Chunk 的迭代器接口，这个改进对于 OLAP 请求的改进非常明显，在 TiDB 的 TPC-H 测试集上能看出来（[TiDB TPC-H 50G 性能测试报告](https://docs.pingcap.com/zh/search/?lang=zh&type=tidb&version=v4.0&q=TPCH)），Chunk 的引入为我们全面的向量化执行和 CodeGen 支持打下了基础。目前在 TiKV 内部对于下推算子的执行还没有使用 Chunk 改造，不过这个已经在计划中，在 TiKV 中这个改进，预期对查询性能的提升也将非常显著。\n\n另一方面，一个数据库查询引擎最核心的组件之一：优化器，在今年也有长足的进步。我们在 2017 年就已经全面引入了基于代价的 SQL 优化（CBO，Cost-Based Optimization），我们在今年改进了我们的代价评估模型，加入了一些新的优化规则，同时实现了 Join Re-Order 等一系列优化，从结果上来看，目前在 TPC-H 的测试集上，对于所有 Query，TiDB 的 SQL 优化器大多已给出了最优的执行计划。CBO 的另一个关键模块是统计信息收集，在今年，我们引入了自动的统计信息收集算法，使优化器的适应性更强。另外针对 OLTP 的场景 TiDB 仍然保留了轻量的 RBO 甚至直接 Bypass 优化器，以提升 OLTP 性能。另外，感谢三星韩国研究院的几位工程师的贡献，他们给 TiDB 引入了 Query Plan Cache，对高并发场景下查询性能的提升也很明显。另外在功能上，我们引入了 Partition Table 的支持，对于一些 Partition 特性很明显的业务，TiDB 能够更加高效的调度数据的写入读取和更新。\n\n![TPC-H Query Result](https://img1.www.pingcap.com/prod/1_522452602e.png)\n\n一直以来，TiDB 的 SQL 层作为纯 Go 语言实现的最完备的 MySQL 语法兼容层，很多第三方的 MySQL 工具在使用着 TiDB 的 SQL Parser，其中的优秀代表比如小米的 Soar（[https://github.com/XiaoMi/soar](https://github.com/XiaoMi/soar)）。为了方便第三方更好的复用 TiDB Parser，我们在 2018 年将 Parser 从主项目中剥离了出来，成为了一个独立的项目：pingcap/parser，希望能帮到更多的人。\n\n说到 TiDB 的底层存储 TiKV 今年也有很多让人眼前一亮的更新。在 TiKV 的基石——一致性算法 Raft 这边，大家知道 TiKV 采用的是 Multi-Raft 的架构，内部通过无数个 Raft Group 动态的分裂、合并、移动以达到动态伸缩和动态负载均衡。我们在今年仍然持续在扩展 Multi-Raft 的边界，我们今年加入了动态的 Raft Group 合并，以减轻元信息存储和心跳通信的负担；给 Raft 扩展了 Learner 角色（只同步 Log 不投票的角色） 为 OLAP Read 打下基础；给 Raft 的基础算法加入了 Pre-Vote 的阶段，让整个系统在异常网络状态下可靠性更高。\n\n![Raft Group Merge](https://img1.www.pingcap.com/prod/2_398d33b88b.png)\n\n<div class=\"caption-center\">Raft Group Merge</div>\n\n在性能方面，我们花了很大的精力重构了我们单机上多 Raft Group 的线程模型（[https://github.com/tikv/tikv/pull/3568](https://github.com/tikv/tikv/pull/3568)）， 虽然还没有合并到 master 分支，在我们测试中，这个优化带来了两倍以上的吞吐提升，同时写入延迟降低至现在的版本的 1/2 ，预计在这两周我们会完成这个巨大的 PR 的 Code Review，各位同学可以期待一下 :)\n\n第三件事情是我们开始将 TiKV 的本地存储引擎的接口彻底抽象出来，目标是能做到对 RocksDB 的弱耦合，这点的意义很大，不管是社区还是我们自己，对新的单机存储引擎支持将变得更加方便。\n\n![截图](https://img1.www.pingcap.com/prod/3_782b921557.png)\n\n**在 TiKV 社区这边，今年的另外一件大事是加入了 CNCF，变成了 CNCF 的托管项目，也是 CNCF 基金会第一个非结构化数据库项目。** 后来很多朋友问我，为什么捐赠的是 TiKV 而不是 TiDB，其实主要的原因就像我在当天的一条 Tweet 说的，TiKV 更像是的一个更加通用的组件，当你有一个可以弹性伸缩的，支持跨行 ACID 事务的 Key-Value 数据库时，你会发现构建其他很多可靠的分布式系统会容易很多，这在我们之后的 [TiDB Hackathon](https://mp.weixin.qq.com/s/mKygN5EQoaaeFMDIFeAzsw)\n中得到了很好的体现。另外社区已经开始出现基于 TiKV 构建的 Redis 协议支持，以及分布式队列系统，例如 [meitu/titan](https://mp.weixin.qq.com/s/2tyAtcmKUU2L1yoE_V3SsA) 项目。作为一个基金会项目，社区不仅仅可以直接使用，更能够将它作为构建其他系统的基石，我觉得更加有意义。类似的，今年我们将我们的 Raft 实现从主项目中独立了出来（pingcap/raft-rs），也是希望更多的人能从中受益。\n\n>*“……其 KV与 SQL分层的方式，刚好符合我们提供 NoSQL 存储和关系型存储的需求，另外，PingCAP 的文档齐全，社区活跃，也已经在实际应用场景有大规模的应用，公司在北京，技术交流也非常方便，事实证明，后面提到的这几个优势都是对的……”*\n>\n>*——美图公司 Titan 项目负责人任勇全对 TiKV 的评论*\n\n在 TiDB 的设计之初，我们坚定将调度和元信息从存储层剥离出来（PD），现在看来，好处正渐渐开始显示出来。今年在 PD 上我们花了很大精力在处理热点探测和快速热点调度，调度和存储分离的架构让我们不管是在开发，测试还是上线新的调度策略时效率很高。瞬时热点一直是分布式存储的最大敌人，如何快速发现和处理，我们也有计划尝试将机器学习引入 PD 的调度中，这是 2019 会尝试的一个事情。总体来说，这个是一个长期的课题。\n\n我在几个月前的一篇文章提到过 TiDB 为什么从 Day-1 起就 All-in Kubernetes （《[十问 TiDB：关于架构设计的一些思考](https://pingcap.com/blog-cn/10-questions-tidb-structure/)》），今年很欣喜的看到，Kubernetes 及其周边生态已经渐渐成熟，已经开始有很多公司用 Kubernetes 来运行 Mission-critical 的系统，这也佐证了我们当年的判断。2018 年下半年，我们也开源了我们的 [TiDB Operator](https://pingcap.com/blog-cn/tidb-operator-introduction/)（[https://github.com/pingcap/tidb-operator](https://github.com/pingcap/tidb-operator)），这个项目并不止是一个简单的在 K8s 上自动化运维 TiDB 的工具，在我们的战略里面，是作为 Cloud TiDB 的重要基座，过去设计一个完善的多租户系统是一件非常困难的事情，同时调度对象是数据库这种带状态服务，更是难上加难，TiDB-Operator 的开源也是希望能够借助社区的力量，一起将它做好。\n\n![多租户 TiDB](https://img1.www.pingcap.com/prod/4_276b2cf12a.png)\n\n<div class=\"caption-center\">多租户 TiDB</div>\n\n今年还做了一件很大的事情，我们成立了一个新的部门 TEP（TiDB Enterprise Platform）专注于商业化组件及相关的交付质量控制。作为一个企业级的分布式数据库，TiDB 今年完成了商业化从0到1的跨越，越来越多的付费客户证明 TiDB 的核心的成熟度已经可以委以重任，成立 TEP 小组也是希望在企业级产品方向上继续发力。从 [TiDB-Lightning](https://pingcap.com/blog-cn/tidb-ecosystem-tools-2/)（MySQL 到 TiDB 高速离线数据导入工具）到 [TiDB-DM](https://pingcap.com/blog-cn/tidb-ecosystem-tools-3/)（TiDB-DataMigration，端到端的数据迁移-同步工具）能看到发力的重点在让用户无缝的从上游迁移到 TiDB 上。另一方面，[TiDB-Binlog](https://pingcap.com/blog-cn/tidb-ecosystem-tools-1/) 虽然不是今年的新东西，但是今年这一年在无数个社区用户的场景中锻炼，越来越稳定。做工具可能在很多人看来并不是那么「高科技」， 很多时候也确实是脏活累活，但是这些经过无数用户场景打磨的周边工具和生态才是一个成熟的基础软件的护城河和竞争壁垒，在 PingCAP 内部，负责工具和外围系统研发的团队规模几乎和内核团队是 1:1 的配比，重要性可见一斑。\n\n在使用场景上，TiDB 的使用规模也越来越大，下面这张图是我们统计的我们已知 TiDB 的用户，包括上线和准上线的用户，**从 1.0 GA 后，几乎是以一个指数函数的曲线在增长，应用的场景也从简单的 MySQL Sharding 替代方案变成横跨 OLTP 到实时数据中台的通用数据平台组件。**\n\n![TiDB 的用户数统计](https://img1.www.pingcap.com/prod/5_16652bf393.png)\n\n<div class=\"caption-center\">TiDB 的用户数统计</div>\n\n今年几个比较典型的用户案例，从美团的横跨 OLTP 和实时数仓的深度实践，到转转的 All-in TiDB 的体验，再到 TiDB 支撑的北京银行的核心交易系统。可以看到，这些案例从互联网公司的离线线数据存储到要求极端 SLA 的传统银行核心交易系统，TiDB 在这些场景里面都发光发热，甚至有互联网公司（转转）都喊出了 All-in TiDB 的口号，我们非常珍视这份信任，一定尽全力做出漂亮的产品，高质量的服务好我们的用户和客户。另一方面，TiDB 也慢慢开始产生国际影响力的，在线视频巨头葫芦软件（Hulu.com），印度最大的在线票务网站 BookMyShow，东南亚最大的电商之一 Shopee 等等都在大规模的使用 TiDB，在北美和欧洲也已经不少准上线和测试中的的巨头互联网公司。\n\n**简单回顾了一下过去的 2018 年，我们看看未来在哪里。**\n\n其实从我们在 2018 年做的几个比较大的技术决策就能看到，2019 年将是上面几个方向的延续。大的方向的几个指导思想是：\n\n1. **Predicable.** （靠谱，在更广泛的场景中，做到行为可预测。）\n\n2. **Make it right before making it fast.**（稳定，先做稳，再做快。）\n\n3. **Ease of use.** （好用，简单交给用户，复杂留给自己。）\n\n对于真正的 HTAP 场景来说，最大的挑战的是如何很好的做不同类型的 workload 隔离和数据结构根据访问特性自适应。我们在这个问题上给出了自己的答案：通过拓展 Raft 的算法，将不同的副本存储成异构的数据结构以适应不同类型的查询。\n\n这个方法有以下好处：\n\n1. 本身在 Multi-Raft 的层面上修改，不会出现由数据传输组件造成的瓶颈（类似 Kafka 或者 DTS），因为 Multi-Raft 本身就是可扩展的，数据同步的单位从 binlog，变成 Raft log，这个效率会更高，进一步降低了同步的延迟。\n\n2. 更好的资源隔离，通过 PD 的调度，可以真正将不同的副本调度到隔离的物理机器上，真正做到互不影响。\n\n![TiDB 2019 年会变成这个样子](https://img1.www.pingcap.com/prod/6_f0300b39a4.png)\n\n<div class=\"caption-center\">TiDB 2019 年会变成这个样子</div>\n\n![Learner 在 HTAP 中的应用](https://img1.www.pingcap.com/prod/7_57f8da25ba.png)\n\n<div class=\"caption-center\">Learner 在 HTAP 中的应用</div>\n\n在执行器方面，我们会继续推进向量化，不出意外的话，今年会完成所有算子的全路径的向量化执行。\n\n这个 HTAP 方案的另一个关键是存储引擎本身。2019 年，我们会引入新的存储引擎，当然第一阶段仍然会继续在 RocksDB 上改进，改进的目标仍然是减小 LSM-Tree 本身的写放大问题。选用的模型是 [WiscKey（FAST16）](https://www.usenix.org/system/files/conference/fast16/fast16-papers-lu.pdf)，WiscKey 的核心思想是将 Value 从 LSM-Tree 中剥离出来，以减少写放大，如果关注 TiKV 的朋友，已经能注意到我们已经在前几天将一个**新存储引擎 Titan**（PingCAP 的 Titan，很遗憾和美图那个项目重名了）合并到了 TiKV 的主干分支，这个 Titan 是我们在 RocksDB 上的 WiscKey 模型的一个实现，除了 WiscKey 的核心本身，我们还加入了对小 KV 的 inline 等优化，Titan 在我们的内部测试中效果很好，对长度随机的 key-value 写入的吞吐基本能达到原生 RocksDB 的 2 - 3 倍，当然性能提升并不是我最关注的，这个引擎对于 TiDB 最大的意义就是，这个引擎将让 TiDB 适应性更强，做到更加稳定，更加「可预测」。\n\n\n![TiKV 新的本地存储引擎 Titan](https://img1.www.pingcap.com/prod/8_bbb4c15f4e.png)\n\n<div class=\"caption-center\">TiKV 新的本地存储引擎 Titan</div>\n\n在 Titan 走向稳定的同时，我们也在调研从头构建一个更适合 TiDB 的 OLTP workload 的存储引擎，前面说到 2018 年做了抽象 TiKV 的本地存储引擎的事情就是为了这个打基础，当然我们仍然会走 LSM-Tree 的路线。这里多提一句，其实很多人都误解了 LSM-Tree 模型的真正优势，在我看来并不是性能，而是：做到可接受的性能的同时，LSM-Tree 的实现非常简单可维护，只有简单的东西才可以依赖，这个决定和我们在 Raft 与 Paxos 之间的选择偏好也是一致的。另外 LSM-Tree 的设计从宏观上来说，更加符合「冷热分层」以适配异构存储介质的想法，这个我相信是未来在存储硬件上的大趋势。\n\n**至于在 OLAP 的存储引擎这边，我们走的就是纯列式存储的路线了，但是会和传统的 Columnar 数据结构的设计不太一样，这块的进展，我们会在 1 月 19 号的 [TiDB DevCon](https://pingcap.com/community-cn/devcon2019/) 上首秀，这里先卖个关子。**\n\n另一个大的方向是事务模型，目前来说，TiDB 从诞生起，事务模型就没有改变过，走的是传统的 Percolator 的 2PC。这个模型的好处是简单，吞吐也不是瓶颈，但是一个比较大的问题是延迟，尤其在跨数据中心的场景中，这里的延迟主要表现在往 TSO 拿时间戳的网络 roundtrip 上，当然了，我目前仍然认为时钟（TSO）是一个必不可少组件，在不降低一致性和隔离级别的大前提下也是目前我们的最好选择，另外 Percolator 的模型也不是没有办法对延迟进行优化，我们其实在 2018 年，针对 Percolator 本身做了一些理论上的改进，减少了几次网络的 roundtrip，也在年中书写了新的 2PC 改进的 [完整的 TLA+ 的证明](https://github.com/pingcap/tla-plus/blob/master/OptimizedCommitTS/OptimizedCommitTS.tla)，证明了这个新算法的正确性，2019 年在这块还会有比较多的改进，其实我们一直在思考，怎么样能够做得更好，选择合适的时机做合适的优化。另外一方面，在事务模型这方面，2PC 在理论和工程上还有很多可以改进的空间，但是现在的当务之急继续的优化代码结构和整体的稳定性，这部分的工作在未来一段时间还是会专注在理论和证明上。另外一点大家可以期待的是，2019 年我们会引入安全的 Follower/Learner Read，这对保持一致性的前提下读的吞吐会提升，另外在跨数据中心的场景，读的延迟会更小。\n\n![TSO](https://img1.www.pingcap.com/prod/9_4cd1b9902f.png)\n\n差不多就这些吧，最后放一句我特别喜欢的丘吉尔的一句名言作为结尾。\n\nSuccess is not final, failure is not fatal: it is the courage to continue that counts.\n\n成功不是终点，失败也并非终结，最重要的是继续前进的勇气。","date":"2019-01-02","author":"黄东旭","fillInMethod":"writeDirectly","customUrl":"for-community-tidb-2019-level-up","file":null,"relatedBlogs":[]},{"id":"Blogs_221","title":"十分钟成为 Contributor 系列 | 支持 AST 还原为 SQL","tags":["TiDB","Contributor","SQL","社区"],"category":{"name":"社区动态"},"summary":"为了实现一些新特性，我们需要为 AST 实现可以还原为 SQL 文本的功能，这篇教程描述如何为 AST 节点添加该功能。首先介绍一些必需的背景知识，然后介绍实现 Restore() 函数的流程，最后会展示一个例子。","body":"## **背景知识**\n\nSQL 语句发送到 TiDB 后首先会经过 parser，从文本 parse 成为 AST（抽象语法树），AST 节点与 SQL 文本结构是一一对应的，我们通过遍历整个 AST 树就可以拼接出一个与 AST 语义相同的 SQL 文本。\n\n对 parser 不熟悉的小伙伴们可以看 [TiDB 源码阅读系列文章（五）TiDB SQL Parser 的实现](https://pingcap.com/blog-cn/tidb-source-code-reading-5/)。\n\n为了控制 SQL 文本的输出格式，并且为方便未来新功能的加入（例如在 SQL 文本中用 “*” 替代密码），我们引入了 `RestoreFlags` 并封装了 `RestoreCtx` 结构（[相关源码](https://github.com/pingcap/parser/blob/9339d225378fa9b50e1bf8373c2040524b96c6af/ast/util.go#L78)）：\n\n```\n// `RestoreFlags` 中的互斥组:\n// [RestoreStringSingleQuotes, RestoreStringDoubleQuotes]\n// [RestoreKeyWordUppercase, RestoreKeyWordLowercase]\n// [RestoreNameUppercase, RestoreNameLowercase]\n// [RestoreNameDoubleQuotes, RestoreNameBackQuotes]\n// 靠前的 flag 拥有更高的优先级。\nconst (\n\tRestoreStringSingleQuotes RestoreFlags = 1 << iota\n\n\t...\n)\n\n// RestoreCtx is `Restore` context to hold flags and writer.\ntype RestoreCtx struct {\n\tFlags RestoreFlags\n\tIn    io.Writer\n}\n\n// WriteKeyWord 用于向 `ctx` 中写入关键字（例如：SELECT）。\n// 它的大小写受 `RestoreKeyWordUppercase`，`RestoreKeyWordLowercase` 控制\nfunc (ctx *RestoreCtx) WriteKeyWord(keyWord string) {\n\t...\n}\n\n// WriteString 用于向 `ctx` 中写入字符串。\n// 它是否被引号包裹及转义规则受 `RestoreStringSingleQuotes`，`RestoreStringDoubleQuotes`，`RestoreStringEscapeBackslash` 控制。\nfunc (ctx *RestoreCtx) WriteString(str string) {\n\t...\n}\n\n// WriteName 用于向 `ctx` 中写入名称（库名，表名，列名等）。\n// 它是否被引号包裹及转义规则受 `RestoreNameUppercase`，`RestoreNameLowercase`，`RestoreNameDoubleQuotes`，`RestoreNameBackQuotes` 控制。\nfunc (ctx *RestoreCtx) WriteName(name string) {\n\t...\n}\n\n// WritePlain 用于向 `ctx` 中写入普通文本。\n// 它将被直接写入不受 flag 影响。\nfunc (ctx *RestoreCtx) WritePlain(plainText string) {\n\t...\n}\n\n// WritePlainf 用于向 `ctx` 中写入普通文本。\n// 它将被直接写入不受 flag 影响。\nfunc (ctx *RestoreCtx) WritePlainf(format string, a ...interface{}) {\n\t...\n}\n```\n\n我们在 `ast.Node` 接口中添加了一个 `Restore(ctx *RestoreCtx) error` 函数，这个函数将当前节点对应的 SQL 文本追加至参数 `ctx` 中，如果节点无效则返回 `error`。\n\n```\ntype Node interface {\n    // Restore AST to SQL text and append them to `ctx`.\n    // return error when the AST is invalid.\n\tRestore(ctx *RestoreCtx) error\n\n    ...\n}\n```\n\n以 SQL 语句 `SELECT column0 FROM table0 UNION SELECT column1 FROM table1 WHERE a = 1` 为例，如下图所示，我们通过遍历整个 AST 树，递归调用每个节点的 `Restore()` 方法，即可拼接成一个完整的 SQL 文本。\n\n![ast-tree](https://img1.www.pingcap.com/prod/ast_tree_f49b2dfb5e.png)\n\n值得注意的是，SQL 文本与 AST 是一个多对一的关系，我们不可能从 AST 结构中还原出与原 SQL 完全一致的文本，\n因此我们只要保证还原出的 SQL 文本与原 SQL **语义相同** 即可。所谓语义相同，指的是由 AST 还原出的 SQL 文本再被解析为 AST 后，两个 AST 是相等的。\n\n我们已经完成了接口设计和测试框架，具体的`Restore()` 函数留空。因此**只需要选择一个留空的 `Restore()` 函数实现，并添加相应的测试数据，就可以提交一个 PR 了！**\n\n## **实现 `Restore()` 函数的整体流程**\n\n1. 请先阅读 [Proposal](https://github.com/pingcap/tidb/tree/master/docs/design/2018-11-29-ast-to-sql-text.md)、[Issue](https://github.com/pingcap/tidb/issues/8532)\n\n2. 在 [Issue](https://github.com/pingcap/tidb/issues/8532) 中找到未实现的函数\n\n    1. 在 [Issue-pingcap/tidb#8532](https://github.com/pingcap/tidb/issues/8532) 中找到一个没有被其他贡献者认领的任务，例如 `ast/expressions.go: BetweenExpr`。\n\n    2. 在 [pingcap/parser](https://github.com/pingcap/parser) 中找到任务对应文件 `ast/expressions.go`。\n\n    3. 在文件中找到 `BetweenExpr` 结构的 `Restore` 函数：\n\n    ```\n    // Restore implements Node interface.\n    func (n *BetweenExpr) Restore(ctx *RestoreCtx) error {\n        return errors.New(\"Not implemented\")\n    }\n    ```\n\n3. 实现 `Restore()` 函数\n\n    根据 Node 节点结构和 SQL 语法实现函数功能。\n\n     > 参考 [MySQL 5.7 SQL Statement Syntax](https://dev.mysql.com/doc/refman/5.7/en/sql-statements.html)\n\n4. 写单元测试\n\n    参考示例在相关文件下添加单元测试。\n\n5. 运行 `make test`，确保所有的 test case 都能跑过。\n\n6. 提交 PR\n\n     PR 标题统一为：`parser: implement Restore for XXX`\n     请在 PR 中关联 Issue: `pingcap/tidb#8532`\n\n## **示例**\n\n这里以[实现 BetweenExpr 的 Restore 函数 PR](https://github.com/pingcap/parser/pull/71/files) 为例，进行详细说明：\n\n1. 首先看 `ast/expressions.go`：\n\n    1. 我们要实现一个 `ast.Node` 结构的 `Restore` 函数，首先清楚该结构代表什么短语，例如 `BetweenExpr` 代表 `expr [NOT] BETWEEN expr AND expr` （参见：[MySQL 语法 - 比较函数和运算符](https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_between)）。\n\n    2. 观察 `BetweenExpr` 结构：\n\n    ```\n    // BetweenExpr is for \"between and\" or \"not between and\" expression.\n    type BetweenExpr struct {\n        exprNode\n        // 被检查的表达式\n        Expr ExprNode\n        // AND 左侧的表达式\n        Left ExprNode\n        // AND 右侧的表达式\n        Right ExprNode\n        // 是否有 NOT 关键字\n        Not bool\n    }\n    ```\n\n    3. 实现 `BetweenExpr` 的 `Restore` 函数：\n\n    ```\n    // Restore implements Node interface.\n    func (n *BetweenExpr) Restore(ctx *RestoreCtx) error {\n        // 调用 Expr 的 Restore，向 ctx 写入 Expr\n        if err := n.Expr.Restore(ctx); err != nil {\n            return errors.Annotate(err, \"An error occurred while restore BetweenExpr.Expr\")\n        }\n        // 判断是否有 NOT，并写入相应关键字\n        if n.Not {\n            ctx.WriteKeyWord(\" NOT BETWEEN \")\n        } else {\n            ctx.WriteKeyWord(\" BETWEEN \")\n        }\n        // 调用 Left 的 Restore\n        if err := n.Left.Restore(ctx); err != nil {\n            return errors.Annotate(err, \"An error occurred while restore BetweenExpr.Left\")\n        }\n        // 写入 AND 关键字\n        ctx.WriteKeyWord(\" AND \")\n        // 调用 Right 的 Restore\n        if err := n.Right.Restore(ctx); err != nil {\n            return errors.Annotate(err, \"An error occurred while restore BetweenExpr.Right \")\n        }\n        return nil\n    }\n    ```\n\n2. 接下来给函数实现添加单元测试, `ast/expressions_test.go`：\n\n    ```\n    // 添加测试函数\n    func (tc *testExpressionsSuite) TestBetweenExprRestore(c *C) {\n        // 测试用例\n        testCases := []NodeRestoreTestCase{\n            {\"b between 1 and 2\", \"`b` BETWEEN 1 AND 2\"},\n            {\"b not between 1 and 2\", \"`b` NOT BETWEEN 1 AND 2\"},\n            {\"b between a and b\", \"`b` BETWEEN `a` AND `b`\"},\n            {\"b between '' and 'b'\", \"`b` BETWEEN '' AND 'b'\"},\n            {\"b between '2018-11-01' and '2018-11-02'\", \"`b` BETWEEN '2018-11-01' AND '2018-11-02'\"},\n        }\n        // 为了不依赖父节点实现，通过 extractNodeFunc 抽取待测节点\n        extractNodeFunc := func(node Node) Node {\n            return node.(*SelectStmt).Fields.Fields[0].Expr\n        }\n        // Run Test\n        RunNodeRestoreTest(c, testCases, \"select %s\", extractNodeFunc)\n    }\n    ```\n\n    **至此 `BetweenExpr` 的 `Restore` 函数实现完成，可以提交 PR 了。为了更好的理解测试逻辑，下面我们看 `RunNodeRestoreTest`：**\n\n    ```\n    // 下面是测试逻辑，已经实现好了，不需要 contributor 实现\n    func RunNodeRestoreTest(c *C, nodeTestCases []NodeRestoreTestCase, template string, extractNodeFunc func(node Node) Node) {\n        parser := parser.New()\n        for _, testCase := range nodeTestCases {\n            // 通过 template 将测试用例拼接为完整的 SQL\n            sourceSQL := fmt.Sprintf(template, testCase.sourceSQL)\n            expectSQL := fmt.Sprintf(template, testCase.expectSQL)\n            stmt, err := parser.ParseOneStmt(sourceSQL, \"\", \"\")\n            comment := Commentf(\"source %#v\", testCase)\n            c.Assert(err, IsNil, comment)\n            var sb strings.Builder\n            // 抽取指定节点并调用其 Restore 函数\n            err = extractNodeFunc(stmt).Restore(NewRestoreCtx(DefaultRestoreFlags, &sb))\n            c.Assert(err, IsNil, comment)\n            // 通过 template 将 restore 结果拼接为完整的 SQL\n            restoreSql := fmt.Sprintf(template, sb.String())\n            comment = Commentf(\"source %#v; restore %v\", testCase, restoreSql)\n            // 测试 restore 结果与预期一致\n            c.Assert(restoreSql, Equals, expectSQL, comment)\n            stmt2, err := parser.ParseOneStmt(restoreSql, \"\", \"\")\n            c.Assert(err, IsNil, comment)\n            CleanNodeText(stmt)\n            CleanNodeText(stmt2)\n            // 测试解析的 stmt 与原 stmt 一致\n            c.Assert(stmt2, DeepEquals, stmt, comment)\n        }\n    }\n    ```\n\n**不过对于 `ast.StmtNode`（例如：`ast.SelectStmt`）测试方法有些不一样，\n由于这类节点可以还原为一个完整的 SQL，因此直接在 `parser_test.go` 中测试。**\n\n下面以[实现 UseStmt 的 Restore 函数 PR](https://github.com/pingcap/parser/pull/62/files) 为例，对测试进行说明：\n\n1. `Restore` 函数实现过程略。\n\n2. 给函数实现添加单元测试，参见 `parser_test.go`：\n\n    在这个示例中，只添加了几行测试数据就完成了测试：\n\n    ```\n    // 添加 testCase 结构的测试数据\n    {\"use `select`\", true, \"USE `select`\"},\n    {\"use `sel``ect`\", true, \"USE `sel``ect`\"},\n    {\"use select\", false, \"USE `select`\"},\n    ```\n\n    我们看 `testCase` 结构声明：\n\n    ```\n    type testCase struct {\n        // 原 SQL\n        src     string\n        // 是否能被正确 parse\n        ok      bool\n        // 预期的 restore SQL\n        restore string\n    }\n    ```\n\n    测试代码会判断原 SQL parse 出 AST 后再还原的 SQL 是否与预期的 restore SQL 相等，具体的测试逻辑在 `parser_test.go` 中 `RunTest()`、`RunRestoreTest()` 函数，逻辑与前例类似，此处不再赘述。\n\n---\n\n加入 TiDB Contributor Club，无门槛参与开源项目，改变世界从这里开始吧（萌萌哒）。\n![tidb-community.png](https://img1.www.pingcap.com/prod/tidb_community_8df81a1aff.png)\n\n> 点击查看更多 [成为 Contributor 系列文章](https://pingcap.com/zh/blog/?tag=Contributor)","date":"2018-12-20","author":"赵一霖","fillInMethod":"writeDirectly","customUrl":"support-ast-restore-to-sql-text","file":null,"relatedBlogs":[]},{"id":"Blogs_198","title":"TiDB 开源社区指南（上）","tags":["TiDB","社区"],"category":{"name":"社区动态"},"summary":"本系列文章旨在帮助社区开发者了解 TiDB 项目的全貌，更好的参与 TiDB 项目开发。上篇会聚焦在社区参与者的角度，描述如何更好的参与 TiDB 项目开发。","body":"本系列文章旨在帮助社区开发者了解 TiDB 项目的全貌，更好的参与 TiDB 项目开发。大致会分两个角度进行描述：\n\n* 从社区参与者的角度描述如何更好的参与 TiDB 项目开发；\n\n* 从 PingCAP 内部团队的角度展示 TiDB 的开发流程，包括版本规划、开发流程、Roadmap 制定等。\n\n希望通过一内一外两条线的描述，读者能在技术之外对 TiDB 有更全面的了解。本篇将聚焦在社区参与者的角度进行描述，也就是“外线”。\n\n## 了解 TiDB\n\n参与一个开源项目第一步总是了解它，特别是对 TiDB 这样一个大型的项目，了解的难度比较高，这里列出一些相关资料，帮助 newcomers 从架构设计到工程实现细节都能有所了解：\n\n* [Overview](https://github.com/pingcap/docs#tidb-introduction)\n* [How we build TiDB](https://pingcap.com/blog/2016-10-17-how-we-build-tidb/)\n* [TiDB 源码阅读系列文章](https://pingcap.com/blog-cn/#%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB)\n* [Deep Dive TiKV (Work-In-Process)](https://github.com/tikv/deep-dive-tikv/)\n\n当然，最高效地熟悉 TiDB 的方式还是使用它，在某些场景下遇到了问题或者是想要新的 feature，去跟踪代码，找到相关的代码逻辑，在这个过程中很容易对相关模块有了解，不少 Contributor 就是这样完成了第一次贡献。 \n\n我们还有一系列的 Infra Meetup，大约两周一次，如果方便到现场的同学可以听到这些高质量的 Talk。除了北京之外，其他的城市（上海、广州、成都、杭州）也开始组织 Meetup，方便更多的同学到现场来面基。\n\n## 发现可以参与的事情\n\n对 TiDB 有基本的了解之后，就可以选一个入手点。在 TiDB repo 中我们给一些简单的 issue 标记了 [for-new-contributors](https://github.com/pingcap/tidb/issues?q=is%3Aissue+is%3Aopen+label%3A%22for+new+contributors%22) 标签，这些 issue 都是我们评估过容易上手的事情，可以以此为切入点。另外我们也会定期举行一些活动，把框架搭好，教程写好，新 Contributor 按照固定的模式即可完成某一特性开发。\n\n当然除了那些标记为 for-new-contributors 的 issue 之外，也可以考虑其他的 issue，标记为 [help-wanted](https://github.com/pingcap/tidb/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) 标签的 issue 可以优先考虑。除此之外的 issue 可能会比较难解决，需要对 TiDB 有较深入的了解或者是对完成时间有较高的要求，不适合第一次参与的同学。\n\n当然除了现有的 issue 之外，也欢迎将自己发现的问题或者是想要的特性提为新的 issue，然后自投自抢 :) 。 \n\n当你已经对 TiDB 有了深入的了解，那么可以尝试从 [Roadmap](https://pingcap.com/docs-cn/v3.0/roadmap/) 上找到感兴趣的事项，和我们讨论一下如何参与。\n\n## 讨论方案\n\n找到一个感兴趣的点之后，可以在 issue 中进行讨论，如果是一个小的 bug-fix 或者是小的功能点，可以简单讨论之后开工。即使再简单的问题，也建议先进行讨论，以免出现解决方案有问题或者是对问题的理解出了偏差，做了无用功。\n\n但是如果要做的事情比较大，可以先写一个详细的设计文档，提交到 [docs/design](https://github.com/pingcap/tidb/tree/master/docs/design) 目录下面，这个目录下有设计模板以及一些已有的设计方案供你参考。一篇好的设计方案要写清楚以下几点：\n\n*   背景知识\n\n*   解决什么问题\n\n*   方案详细设计\n\n*   对方案的解释说明，证明正确性和可行性\n\n*   和现有系统的兼容性\n\n*   方案的具体实现 \n\n用一句话来总结就是写清楚“你做了什么，为什么要做这个，怎么做的，为什么要这样做”。如果对自己的方案不太确定，可以先写一个 Google Doc，share 给我们简单评估一下，再提交 PR。\n\n## 提交 PR\n\n按照方案完成代码编写后，就可以提交 PR。当然如果开发尚未完成，在某些情况下也可以先提交 PR，比如希望先让社区看一下大致的解决方案，这个时候请将 PR 标记为 WIP。\n\n对于 PR 我们有一些要求：\n\n1. 需要能通过 `make dev` 的测试，跑过基本的单元测试；\n\n2. 必须有测试，除非只是改动文档或者是依赖包，其他情况需要有充足的理由说明没有测试的原因；\n\n3. 代码以及注释的质量需要足够高，查看 [Code style](https://github.com/pingcap/community/blob/master/CONTRIBUTING.md#code-style) 有一些关于编码风格和 commit message 的 guide；\n\n4. 请尽可能详细的填写 PR 的描述，并打上合适的 label。\n\n**对于 PR 的描述，我们提供了一个模板，希望大家能够认真填写，一个好的描述能够加速 PR 的 review 过程。通过这个模板能够向 reviewers 以及社区讲明白：**\n\n* 这个PR 解决什么问题：相关的问题描述或者是 issue 链接；\n\n* 如何解决：具体的解决方法，reviewers 会根据这里的描述去看代码变动，所以请将这一段写的尽可能详细且有帮助；\n\n* 测试的情况；\n\n* 其他相关信息（如果需要）：benchmark 结果、兼容性问题、是否需要更新文档。\n\n最后再说几句测试，正确性是数据库安身立命之本，怎么强调测试都不为过。PR 中的测试不但需要充足，覆盖到所做的变动，还需要足够清晰，通过代码或者注释来表达测试的目的，帮助 reviewer 以及今后可能变动/破坏相关逻辑的人能够容易的理解这段测试。一段完善且清晰的测试也有利于让 reviewer 相信这个 Patch 是正确的。\n\n## PR review\n\nPR review 的过程就是 reviewer 不断地提出 comment，PR 作者持续解决 comment 的过程。\n\n**每个 PR 在合并之前都需要至少得到两个 Committer/Maintainer 的 LGTM，一些重要的 PR 需要得到三个，比如对于 DDL 模块的修改，默认都需要得到三个 LGTM。**\n\n#### Tips：\n\n* 提了PR 之后，可以 at 一下相关的同学来 review；\n\n* Address comment 之后可以 at 一下之前提过 comment 的同学，标准做法是 comment 一下 “**PTAL @xxx**”，这样我们内部的 Slack 中可以得到通知，相关的同学会受到提醒，让整个流程更紧凑高效。\n\n## 与项目维护者之间的交流\n\n**目前标准的交流渠道是 GitHub issue**，请大家优先使用这个渠道，我们有专门的同学来维护这个渠道，其他渠道不能保证得到研发同学的及时回复。这也是开源项目的标准做法。\n\n无论是遇到 bug、讨论具体某一功能如何做、提一些建议、产品使用中的疑惑，都可以来提 issue。在开发过程中遇到了问题，也可以在相关的 issue 中进行讨论，包括方案的设计、具体实现过程中遇到的问题等等。\n\n**最后请大家注意一点，除了 pingcap/docs-cn 这个 repo 之外，请大家使用英文。**\n\n## 更进一步\n\n当你完成上面这些步骤的之后，恭喜你已经跨过第一个门槛，正式进入了 TiDB 开源社区，开始参与 TiDB 项目开发，成为 TiDB Contributor。\n\n如果想更进一步，深入了解 TiDB 的内部机制，掌握一个分布式数据库的核心模块，并能做出改进，那么可以了解更多的模块，提更多的 PR，进一步向 Committer 发展（[Become a Committer](https://github.com/pingcap/community/blob/master/become-a-committer.md) 这篇文档解释了什么是 Committer）。目前 TiDB 社区的 Committer 还非常少，我们希望今后能出现更多的 Committer 甚至是 Maintainer。\n\n从 Contributor 到 Committer 的门槛比较高，比如今年的新晋 Committer 杜川同学，在成为 Committer 的道路上给 tidb/tikv 项目提交了大约 80 个 PR，并且对一些模块有非常深入的了解。当然，成为 Committer 之后，会有一定的权利，比如对一些 PR 点 LGTM 的权利，参加 PingCAP 内部的技术事项、开发规划讨论的权利，参加定期举办的 TechDay/DevCon 的权利。目前社区中还有几位贡献者正走在从 Contributor 到 Committer 的道路上。","date":"2018-11-09","author":"申砾","fillInMethod":"writeDirectly","customUrl":"tidb-community-guide-1","file":null,"relatedBlogs":[]},{"id":"Blogs_79","title":"三十分钟成为 Contributor | 为 TiKV 添加 built-in 函数","tags":["TiKV","社区","Contributor"],"category":{"name":"社区动态"},"summary":"手把手教你如何在三十分钟内成为 TiKV 项目的 Contributor。","body":"## 背景知识\n\nSQL 语句发送到 TiDB 后经过 parser 生成 AST（抽象语法树），再经过 Query Optimizer 生成执行计划，执行计划切分成很多子任务，这些子任务以表达式的方式最后下推到底层的各个 TiKV 来执行。\n\n![](https://img1.www.pingcap.com/prod/1_d7247c79ca.png)\n\n<div class=\"caption-center\">图 1</div>\n\n如图 1，当 TiDB 收到来自客户端的查询请求\n\n`select count(*) from t where a + b > 5`\n\n时，执行顺序如下：\n\n1. TiDB 对 SQL 进行解析，组织成对应的表达式，下推给 TiKV\n\n2. TiKV 收到请求后，循环以下过程\n\n\t* 获取下一行完整数据，并按列解析\n\n\t* 使用参数中的 where 表达式对数据进行过滤\n\n\t* 若上一条件符合，进行聚合计算\n\n3. TiKV 向 TiDB 返回聚合计算结果\n\n4. TiDB 对所有涉及的结果进行二次聚合，返回给客户端\n\n这里的 where 条件便是以表达式树的形式下推给 TiKV。在此之前 TiDB 只会向 TiKV 下推一小部分简单的表达式，比如取出某一个列的某个数据类型的值，简单数据类型的比较操作，算术运算等。为了充分利用分布式集群的资源，进一步提升 SQL 在整个集群的执行速度，我们需要将更多种类的表达式下推到 TiKV 来运行，其中的一大类就是 MySQL built-in 函数。\n\n目前，由于 TiKV 的 built-in 函数尚未全部实现，对于无法下推的表达式，TiDB 只能自行解决。这无疑将成为提升 TiDB 速度的最大绊脚石。好消息是，TiKV 在实现 built-in 函数时，可以直接参考 TiDB 的对应函数逻辑（顺便可以帮 TiDB 找找 Bug），为我们减少了不少工作量。\n\n**Built-in 函数无疑是 TiDB 和 TiKV 成长道路上不可替代的一步，如此艰巨又庞大的任务，我们需要广大社区朋友们的支持与鼓励。亲爱的朋友们，想玩 Rust 吗？想给 TiKV 提 PR 吗？想帮助 TiDB 跑得更快吗？动动您的小手指，拿 PR 来砸我们吧。您的 PR 一旦被采用，将会有小惊喜哦。**\n\n## 手把手教你实现 built-in 函数\n\n### Step 1：准备下推函数\n\n在 TiKV 的 [https://github.com/tikv/tikv/issues/3275](https://github.com/tikv/tikv/issues/3275) issue 中，找到未实现的函数签名列表，选一个您想要实现的函数。\n\n### Step 2：获取 TiDB 中可参考的逻辑实现\n\n在 TiDB 的 [expression](https://github.com/pingcap/tidb/tree/master/expression) 目录下查找相关 builtinXXXSig 对象，这里 XXX 为您要实现的函数签名，本例中以 [MultiplyIntUnsigned](https://github.com/tikv/tikv/pull/3277) 为例，可以在 TiDB 中找到其对应的函数签名（`builtinArithmeticMultiplyIntUnsignedSig`）及 [实现](https://github.com/pingcap/tidb/blob/master/expression/builtin_arithmetic.go#L532)。\n\n### Step 3：确定函数定义\n\n1. built-in 函数所在的文件名要求与 TiDB 的名称对应，如 TiDB 中，[expression](https://github.com/pingcap/tidb/tree/master/expression) 目录下的下推文件统一以 builtin_XXX 命名，对应到 TiKV 这边，就是 `builtin_XXX.rs`。若同名对应的文件不存在，则需要自行在同级目录下新建。对于本例，当前函数存放于 TiDB 的 [builtin_arithmetic.go](https://github.com/pingcap/tidb/blob/master/expression/builtin_arithmetic.go#L532) 文件里，对应到 TiKV 便是存放在 [builtin_arithmetic.rs](https://github.com/tikv/tikv/blob/master/components/tidb_query/src/expr/builtin_arithmetic.rs) 中。\n\n2. 函数名称：函数签名转为 Rust 的函数名称规范，这里 `MultiplyIntUnsigned` 将会被定义为 `multiply_int_unsigned`。\n\n3. 函数返回值，可以参考 TiDB 中实现的 `Eval` 函数，对应关系如下：\n\n    | TiDB 对应实现的 Eval 函数 | TiKV 对应函数的返回值类型 |\n    | ----------------------- | ---------------------- |\n    | `evalInt` | `Result<Option<i64>>` |\n    | `evalReal` | `Result<Option<f64>>` |\n    | `evalString` | `Result<Option<Cow<'a, [u8]>>>` |\n    | `evalDecimal` | `Result<Option<Cow<'a, Decimal>>>` |\n    | `evalTime` | `Result<Option<Cow<'a, Time>>>` |\n    | `evalDuration` | `Result<Option<Cow<'a, Duration>>>`|\n    | `evalJSON` | `Result<Option<Cow<'a, Json>>>`|\n\n    可以看到 TiDB 的 `builtinArithmeticMultiplyIntUnsignedSig`  对象实现了 evalInt 方法，故当前函数（`multiply_int_unsigned`）的返回类型应该为 `Result<Option<i64>>`。\n\n4. 函数的参数, 所有 builtin-in 的参数都与 Expression 的 `eval` 函数一致，即：\n\n\t* 环境配置量 (ctx:&StatementContext)\n\n\t* 该行数据每列具体值 (row:&[Datum])\n\n综上，`multiply_int_unsigned` 的下推函数定义为：\n\n```\n    pub fn multiply_int_unsigned(\n       &self,\n       ctx: &mut EvalContext,\n       row: &[Datum],\n   ) -> Result<Option<i64>>\n```  \n\n\n### Step 4：实现函数逻辑\n\n这一块相对简单，直接对照 TiDB 的相关逻辑实现即可。这里，我们可以看到 TiDB 的 `builtinArithmeticMultiplyIntUnsignedSig` 的具体实现如下：\n\n```\nfunc (s *builtinArithmeticMultiplyIntUnsignedSig) evalInt(row types.Row) (val int64, isNull bool, err error) {\n  a, isNull, err := s.args[0].EvalInt(s.ctx, row)\n  if isNull || err != nil {\n     return 0, isNull, errors.Trace(err)\n  }\n  unsignedA := uint64(a)\n  b, isNull, err := s.args[1].EvalInt(s.ctx, row)\n  if isNull || err != nil {\n     return 0, isNull, errors.Trace(err)\n  }\n  unsignedB := uint64(b)\n  result := unsignedA * unsignedB\n  if unsignedA != 0 && result/unsignedA != unsignedB {\n     return 0, true, types.ErrOverflow.GenByArgs(\"BIGINT UNSIGNED\", fmt.Sprintf(\"(%s * %s)\", s.args[0].String(), s.args[1].String()))\n  }\n  return int64(result), false, nil\n}\n```\n\n参考以上代码，翻译到 TiKV 即可，如下：\n\n```\n pub fn multiply_int_unsigned(\n       &self,\n       ctx: &mut EvalContext,\n       row: &[Datum],\n   ) -> Result<Option<i64>> {\n       let lhs = try_opt!(self.children[0].eval_int(ctx, row));\n       let rhs = try_opt!(self.children[1].eval_int(ctx, row));\n       let res = (lhs as u64).checked_mul(rhs as u64).map(|t| t as i64);\n       // TODO: output expression in error when column's name pushed down.\n       res.ok_or_else(|| Error::overflow(\"BIGINT UNSIGNED\", &format!(\"({} * {})\", lhs, rhs)))\n           .map(Some)\n   }\n```\n\n### Step 5：添加参数检查\n\nTiKV 在收到下推请求时，首先会对所有的表达式进行检查，表达式的参数个数检查就在这一步进行。\n\nTiDB 中对每个 built-in 函数的参数个数有严格的限制，这一部分检查可参考 TiDB 同目录下 builtin.go 相关代码。\n\n在 TiKV 同级目录的 `scalar_function.rs` 文件里，找到 ScalarFunc 的 `check_args` 函数，按照现有的模式，加入参数个数的检查即可。\n\n### Step 6：添加下推支持\n\nTiKV 在对一行数据执行具体的 expression 时，会调用 `eval` 函数，`eval` 函数又会根据具体的返回类型，执行具体的子函数。这一部分工作在 `scalar_function.rs` 中以宏（dispatch_call）的形式完成。\n\n对于 `MultiplyIntUnsigned`, 我们最终返回的数据类型为 Int，所以可以在 dispatch_call 中找到 `INT_CALLS`，然后照着加入 `MultiplyIntUnsigned => multiply_int_unsigned` , 表示当解析到函数签名 `MultiplyIntUnsigned` 时，调用上述已实现的函数 `multiply_int_unsigned`。\n\n至此 `MultiplyIntUnsigned` 下推逻辑已完全实现。\n\n### Step 7：添加测试\n\n在函数 `multiply_int_unsigned` 所在文件 [builtin_arithmetic.rs](https://github.com/tikv/tikv/blob/master/components/tidb_query/src/expr/builtin_arithmetic.rs) 底部的 test 模块中加入对该函数签名的单元测试，要求覆盖到上述添加的所有代码，这一部分也可以参考 TiDB 中相关的测试代码。本例在 TiKV 中实现的测试代码如下：\n\n```\n    #[test]\n   fn test_multiply_int_unsigned() {\n       let cases = vec![\n           (Datum::I64(1), Datum::I64(2), Datum::U64(2)),\n           (\n               Datum::I64(i64::MIN),\n               Datum::I64(1),\n               Datum::U64(i64::MIN as u64),\n           ),\n           (\n               Datum::I64(i64::MAX),\n               Datum::I64(1),\n               Datum::U64(i64::MAX as u64),\n           ),\n           (Datum::U64(u64::MAX), Datum::I64(1), Datum::U64(u64::MAX)),\n       ];\n       let mut ctx = EvalContext::default();\n       for (left, right, exp) in cases {\n           let lhs = datum_expr(left);\n           let rhs = datum_expr(right);\n           let mut op = Expression::build(\n               &mut ctx,\n               scalar_func_expr(ScalarFuncSig::MultiplyIntUnsigned, &[lhs, rhs]),\n           ).unwrap();\n           op.mut_tp().set_flag(types::UNSIGNED_FLAG as u32);\n           let got = op.eval(&mut ctx, &[]).unwrap();\n           assert_eq!(got, exp);\n       }\n       // test overflow\n       let cases = vec![\n           (Datum::I64(-1), Datum::I64(2)),\n           (Datum::I64(i64::MAX), Datum::I64(i64::MAX)),\n           (Datum::I64(i64::MIN), Datum::I64(i64::MIN)),\n       ];\n       for (left, right) in cases {\n           let lhs = datum_expr(left);\n           let rhs = datum_expr(right);\n           let mut op = Expression::build(\n               &mut ctx,\n               scalar_func_expr(ScalarFuncSig::MultiplyIntUnsigned, &[lhs, rhs]),\n           ).unwrap();\n           op.mut_tp().set_flag(types::UNSIGNED_FLAG as u32);\n           let got = op.eval(&mut ctx, &[]).unwrap_err();\n           assert!(check_overflow(got).is_ok());\n       }\n   }\n```\n\n### Step 8：运行测试\n\n运行 make expression，确保所有的 test case 都能跑过。\n\n完成以上几个步骤之后，就可以给 TiKV 项目提 PR 啦。想要了解提 PR 的基础知识，尝试移步 [此文](https://pingcap.com/blog-cn/how-to-contribute/)，看看是否有帮助。  \n> 点击查看更多 [成为 Contributor 系列文章](https://pingcap.com/zh/blog/?tag=Contributor)","date":"2018-08-01","author":"吴雪莲","fillInMethod":"writeDirectly","customUrl":"30mins-become-contributor-of-tikv","file":null,"relatedBlogs":[]},{"id":"Blogs_105","title":"十分钟成为 Contributor 系列 | 重构内建函数进度报告","tags":["TiDB","Contributor","社区"],"category":{"name":"社区动态"},"summary":"为了方便社区同学更好地参与 TiDB 项目，本文一方面对继上一篇文章发布后参考社区的反馈对表达式计算框架所做的修改进行详细介绍，另一方面对尚未重写的 built-in 函数进行陈列。","body":"6 月 22 日，TiDB 发布了一篇如何十分钟成为 TiDB Contributor 系列的[十分钟成为 Contributor 系列 | 为 TiDB 重构 built-in 函数](https://pingcap.com/blog-cn/reconstruct-built-in-function)，向大家介绍如何为 TiDB 重构 built-in 函数。\n\n截止到目前，得到了来自社区的积极支持与热情反馈，TiDB 参考社区 contributors 的建议，对计算框架进行了部分修改以降低社区同学参与的难度。\n\n本文完成以下**2 项工作**，希望帮助社区更好的参与进 TiDB 的项目中来:\n\n1. 对尚未重写的 built-in 函数进行陈列\n2. 对继上篇文章后，计算框架所进行的修改，进行详细介绍\n\n### 一. 尚未重写的 built-in 函数陈列如下：\n\n共计 165 个\n在 expression 目录下运行 `grep -rn \"^\\tbaseBuiltinFunc$\" -B 1 * | grep \"Sig struct {\" | awk -F \"Sig\" '{print $1}' | awk -F \"builtin\" '{print $3}' > ~/Desktop/func.txt` 命令可以获得所有未实现的 built-in 函数\n\n|       0       |            1             |       2       |        3        | 4 |\n|:-------------:|:------------------------:|:-------------:|:---------------:|:-:|\n|   Coalesce    |        Uncompress        |     Log10     |     Default     | UnaryOp |\n|   Greatest    |    UncompressedLength    |     Rand      |    InetAton     | IsNull |\n|     Least     | ValidatePasswordStrength |      Pow      |    InetNtoa     | In |\n|   Interval    |         Database         |     Round     |    Inet6Aton    | Row |\n|   CaseWhen    |        FoundRows         |     Conv      |    Inet6Ntoa    | SetVar |\n|      If       |       CurrentUser        |     CRC32     |   IsFreeLock    | GetVar |\n|    IfNull     |           User           |     Sqrt      |     IsIPv4      | Values |\n|    NullIf     |       ConnectionID       |  Arithmetic   | IsIPv4Prefixed  | BitCount |\n|  AesDecrypt   |       LastInsertID       |     Acos      |     IsIPv6      | Reverse |\n|  AesEncrypt   |         Version          |     Asin      |   IsUsedLock    | Convert |\n|   Compress    |        Benchmark         |     Atan      |  MasterPosWait  | Substring |\n|    Decode     |         Charset          |      Cot      |    NameConst    | SubstringIndex |\n|  DesDecrypt   |       Coercibility       |      Exp      | ReleaseAllLocks | Locate |\n|  DesEncrypt   |        Collation         |      PI       |      UUID       | Hex |\n|    Encode     |         RowCount         |    Radians    |    UUIDShort    | UnHex |\n|    Encrypt    |          Regexp          |   Truncate    |     AndAnd      | Trim |\n|  OldPassword  |           Abs            |     Sleep     |      OrOr       | LTrim |\n|  RandomBytes  |           Ceil           |     Lock      |    LogicXor     | RTrim |\n|     SHA1      |          Floor           |  ReleaseLock  |      BitOp      | Rpad |\n|     SHA2      |           Log            |   AnyValue    |    IsTrueOp     | BitLength |\n|     Char      |          Format          |   FromDays    |    DayOfWeek    | Timestamp |\n|  CharLength   |        FromBase64        |     Hour      |    DayOfYear    | AddTime |\n|   FindInSet   |        InsertFunc        |    Minute     |      Week       | ConvertTz |\n|     Field     |          Instr           |    Second     |     WeekDay     | MakeTime |\n|    MakeSet    |         LoadFile         |  MicroSecond  |   WeekOfYear    | PeriodAdd |\n|      Oct      |           Lpad           |     Month     |      Year       | PeriodDiff |\n|     Quote     |           Date           |   MonthName   |    YearWeek     | Quarter |\n|      Bin      |         DateDiff         |      Now      |  FromUnixTime   | SecToTime |\n|      Elt      |         TimeDiff         |    DayName    |    GetFormat    | SubTime |\n|   ExportSet   |        DateFormat        |  DayOfMonth   |    StrToDate    | TimeFormat |\n|    UTCTim     |        ToSeconds         | TimestampDiff |    DateArith    | Extract |\n| UnixTimestamp |       UTCTimestamp       |    UTCDate    |      Time       | CurrentTime |\n|    ToDays     |       TimestampAdd       |   TimeToSec   |   CurrentDate   | SysDate |\n\n### 二. 计算框架进行的修改:\n\n此处依然使用 Length 函数( expression/builtin_string.go )为例进行说明，与前文采取相同目录结构:\n\n**1. expression/builtin_string.go**\n\n（1）`lengthFunctionClass.getFunction()` 方法: **简化类型推导实现**\n\ngetFunction 方法用来生成 built-in 函数对应的函数签名，在[构造 ScalarFunction](https://github.com/pingcap/tidb/blob/master/expression/scalar_function.go#L76) 时被调用\n\n``` go\nfunc (c *lengthFunctionClass) getFunction(args []Expression, ctx context.Context) (builtinFunc, error) {\n    // 此处简化类型推导过程，对 newBaseBuiltinFuncWithTp() 实现进行修改，新的实现中，传入 Length 返回值类型 tpInt 表示返回值类型为 int，参数类型 tpString 表示返回值类型为 string\n  bf, err := newBaseBuiltinFuncWithTp(args, ctx, tpInt, tpString)\n  if err != nil {\n    return nil, errors.Trace(err)\n  }\n  // 此处参考 MySQL 实现，设置返回值长度为 10(character length)\n  // 对于 int/double/decimal/time/duration 类型返回值，已在 newBaseBuiltinFuncWithTp() 中默认调用 types.setBinChsClnFlag() 方法，此处无需再进行设置\n  bf.tp.Flen = 10\n  sig := &builtinLengthSig{baseIntBuiltinFunc{bf}}\n  return sig.setSelf(sig), errors.Trace(c.verifyArgs(args))\n}\n```\n\n***注：***\n\n- 对于**返回值类型为 string** 的函数，需要，注意参考 MySQL 行为设置\n\n    `bf.tp.[charset | collate | flag]`\n查看 MySQL 行为可以通过在终端启动\n\n    ` $ mysql -uroot \\-\\-column-type-info`，这样对于每一个查询语句，可以查看每一列详细的 metadata\n对于返回值类型为 string 的函数，以 [concat](https://github.com/pingcap/tidb/blob/master/expression/builtin_string.go#L204) 为例，当存在类型为 string 且包含 binary flag 的参数时，其返回值也应设置 binary flag\n\n- 对于**返回值类型为 Time** 的函数，需要注意，根据函数行为，设置\n\n    `bf.tp.Tp = [ TypeDate | TypeDatetime | TypeTimestamp ]` ，\n  若为 `TypeDate/ TypeDatetime`，还需注意推导 `bf.tp.Decimal` (即小数位数)\n\n- 不确定性的函数：\n\n|   0    |      1       |      2       |      3      |     4      |    5     |\n|:------:|:------------:|:------------:|:-----------:|:----------:|:--------:|\n|  Rand  | ConnectionID | CurrentUser  |    User     |  Database  | RowCount |\n| Schema |  FoundRows   | LastInsertId |   Version   |   Sleep    |   UUID   |\n| GetVar |    SetVar    |    Values    | SessionUser | SystemUser |          |\n\n（2）实现 `builtinLengthSig.evalInt()` 方法：保持不变，此处请注意修改该函数的注释 (s/ eval/ evalXXX)\n\n**2. expression/builtin_string_test.go**\n\n```go\nfunc (s *testEvaluatorSuite) TestLength(c *C) {\n   defer testleak.AfterTest(c)()\n   cases := []struct {\n      args     interface{}\n      expected int64\n      isNil    bool\n      getErr   bool\n   }{\n     ......\n   }\n\n   for _, t := range cases {\n      f, err := newFunctionForTest(s.ctx, ast.Length, primitiveValsToConstants([]interface{}{t.args})...)\n      c.Assert(err, IsNil)\n      d, err := f.Eval(nil)\n     // 注意此处不再对 LENGTH 函数的返回值类型进行测试，相应测试被移动到 plan/typeinfer_test.go/TestInferType 函数中，(注意不是expression/typeinferer_test.go）\n      if t.getErr {\n         c.Assert(err, NotNil)\n      } else {\n         c.Assert(err, IsNil)\n         if t.isNil {\n            c.Assert(d.Kind(), Equals, types.KindNull)\n         } else {\n            c.Assert(d.GetInt64(), Equals, t.expected)\n         }\n      }\n   }\n\n   // 测试函数是否具有确定性\n   // 在 review 社区的 PRs 过程中发现，这个测试经常会被遗漏，烦请留意\n   f, err := funcs[ast.Length].getFunction([]Expression{Zero}, s.ctx)\n   c.Assert(err, IsNil)\n   c.Assert(f.isDeterministic(), IsTrue)\n}\n```\n\n**3. executor/executor_test.go**\n\n与上一篇文章保持不变，需要注意的是，为了保证可读性， `TestStringBuiltin()` 方法仅对 `expression/builtin_string.go` 文件中的 built-in 函数进行测试。如果 `executor_test.go` 文件中不存在对应的 `TestXXXBuiltin()` 方法，可以新建一个对应的测试函数。\n\n**4. plan/typeinfer_test.go**\n\n```go\nfunc (s *testPlanSuite) TestInferType(c *C) {\n  ....\n   tests := []struct {\n      sql     string\n      tp      byte\n      chs     string\n      flag    byte\n      flen    int\n      decimal int\n   }{\n     ...\n     // 此处添加对 length 函数返回值类型的测试\n     // 此处注意，对于返回值类型、长度等受参数影响的函数，此处测试请尽量覆盖全面\n      {\"length(c_char, c_char)\", mysql.TypeLonglong, charset.CharsetBin, mysql.BinaryFlag, 10, 0},\n     ...\n   }\n   for _, tt := range tests {\n      ...\n   }\n}\n```\n\n***注：***\n\n当有多个 PR 同时在该文件中添加测试时，若有别的 contributor 的 PR 先于自己的 PR merge 进 master，有可能会发生冲突，此时在本地 merge 一下 master 分支，解决一下再 push 一下即可。\n\n----------------\n\n**成为 New Contributor 赠送限量版马克杯**的活动还在继续中，任何一个新加入集体的小伙伴都将收到我们充满了诚意的礼物，很荣幸能够认识你，也很高兴能和你一起坚定地走得更远。\n\n#### 成为 New Contributor 获赠限量版马克杯，马克杯获取流程如下：\n\n1. 提交 PR\n2. PR提交之后，请耐心等待维护者进行 Review。\n   - 目前一般在一到两个工作日内都会进行 Review，如果当前的 PR 堆积数量较多可能回复会比较慢。\n   - 代码提交后 CI 会执行我们内部的测试，你需要保证所有的单元测试是可以通过的。期间可能有其它的提交会与当前 PR 冲突，这时需要修复冲突。\n   - 维护者在 Review 过程中可能会提出一些修改意见。修改完成之后如果 reviewer 认为没问题了，你会收到 LGTM(looks good to me) 的回复。当收到两个及以上的 LGTM 后，该 PR 将会被合并。\n3. 合并 PR 后自动成为 Contributor，会收到来自 PingCAP Team 的感谢邮件，请查收邮件并填写领取表单\n   - 表单填写地址：[http://cn.mikecrm.com/01wE8tX](http://cn.mikecrm.com/01wE8tX)\n4. 后台 AI 核查 GitHub ID 及资料信息，确认无误后随即便快递寄出属于你的限量版马克杯\n5. 期待你分享自己参与开源项目的感想和经验，TiDB Contributor Club 将和你一起分享开源的力量\n\n\n了解更多关于 TiDB 的资料请登陆我们的官方网站：[https://pingcap.com](https://pingcap.com)\n\n加入 TiDB Contributor Club 请添加我们的 AI 微信：\n\n![二维码](https://img1.www.pingcap.com/prod/1_45cf0e3c25.jpg)  \n> 点击查看更多 [成为 Contributor 系列文章](https://pingcap.com/zh/blog/?tag=Contributor)","date":"2017-07-14","author":"徐怀宇","fillInMethod":"writeDirectly","customUrl":"reconstruct-built-in-function-report","file":null,"relatedBlogs":[]},{"id":"Blogs_12","title":"十分钟成为 Contributor 系列 | 为 TiDB 重构 built-in 函数","tags":["TiDB","社区","Contributor"],"category":{"name":"社区动态"},"summary":"为了加速表达式计算速度，最近我们对表达式的计算框架进行了重构，这篇教程为大家分享如何利用新的计算框架为 TiDB 重写或新增 built-in 函数。","body":"这是十分钟成为 TiDB Contributor 系列的第二篇文章，让大家可以无门槛参与大型开源项目，感谢社区为 TiDB 带来的贡献，也希望参与 TiDB Community 能为你的生活带来更多有意义的时刻。\n\n为了加速表达式计算速度，最近我们对表达式的计算框架进行了重构，这篇教程为大家分享如何利用新的计算框架为 TiDB 重写或新增 built-in 函数。对于部分背景知识请参考[《十分钟成为 TiDB Contributor 系列 | 添加內建函数》](https://pingcap.com/blog-cn/add-a-built-in-function)这篇文章，本文将首先介绍利用新的表达式计算框架重构 built-in 函数实现的流程，然后以一个函数作为示例进行详细说明，最后介绍重构前后表达式计算框架的区别。\n\n## 重构 built-in 函数整体流程\n\n1. 在 TiDB 源码 expression 目录下选择任一感兴趣的函数，假设函数名为 XX\n\n2. 重写 **XXFunctionClass.getFunction()** 方法\n\n   - 该方法参照 MySQL 规则，根据 built-in 函数的参数类型推导函数的返回值类型\n   - 根据参数的个数、类型、以及函数的返回值类型生成不同的函数签名，关于函数签名的详细介绍见文末附录\n\n3. 实现该 built-in 函数对应的所有函数签名的 **evalYY()** 方法，此处 YY 表示该函数签名的返回值类型\n\n4. 添加测试：\n\n   - 在 expression 目录下，完善已有的 TestXX() 方法中关于该函数实现的测试\n   - 在 executor 目录下，添加 SQL 层面的测试\n\n5. 运行 make dev，确保所有的 test cast 都能跑过\n\n## 示例\n\n这里以重写 LENGTH() 函数的 PR 为例，进行详细说明\n\n**首先看 expression/builtin_string.go:**\n\n（1）实现 lengthFunctionClass.getFunction() 方法\n\n该方法主要完成两方面工作：\n\n1. 参照 MySQL 规则推导 LEGNTH 的返回值类型\n2. 根据 LENGTH 函数的参数个数、类型及返回值类型生成函数签名。由于 LENGTH 的参数个数、类型及返回值类型只存在确定的一种情况，因此此处没有定义新的函数签名类型，而是修改已有的 builtinLengthSig，使其**组合了 baseIntBuiltinFunc（表示该函数签名返回值类型为 int）**\n\n\n```go\ntype builtinLengthSig struct {\n\tbaseIntBuiltinFunc\n}\n\nfunc (c *lengthFunctionClass) getFunction(args []Expression, ctx context.Context) (builtinFunc, error) {\n\t// 参照 MySQL 规则，对 LENGTH 函数返回值类型进行推导\n\ttp := types.NewFieldType(mysql.TypeLonglong)\n\ttp.Flen = 10\n\ttypes.SetBinChsClnFlag(tp)\n\n\t// 根据参数个数、类型及返回值类型生成对应的函数签名，注意此处与重构前不同，使用的是 newBaseBuiltinFuncWithTp 方法，而非 newBaseBuiltinFunc 方法\n\t// newBaseBuiltinFuncWithTp 的函数声明中，args 表示函数的参数，tp 表示函数的返回值类型，argsTp 表示该函数签名中所有参数对应的正确类型\n\t// 因为 LENGTH 的参数个数为1，参数类型为 string，返回值类型为 int，因此此处传入 tp 表示函数的返回值类型，传入 tpString 用来标识参数的正确类型。对于多个参数的函数，调用 newBaseBuiltinFuncWithTp 时，需要传入所有参数的正确类型\n\tbf, err := newBaseBuiltinFuncWithTp(args, tp, ctx, tpString)\n\tif err != nil {\n\t\treturn nil, errors.Trace(err)\n\t}\n\tsig := &builtinLengthSig{baseIntBuiltinFunc{bf}}\n\treturn sig.setSelf(sig), errors.Trace(c.verifyArgs(args))\n}\n```\n\n\n(2) 实现 builtinLengthSig.evalInt() 方法\n\n\n```go\nfunc (b *builtinLengthSig) evalInt(row []types.Datum) (int64, bool, error) {\n\t// 对于函数签名 builtinLengthSig，其参数类型已确定为 string 类型，因此直接调用 b.args[0].EvalString() 方法计算参数\n\tval, isNull, err := b.args[0].EvalString(row, b.ctx.GetSessionVars().StmtCtx)\n\tif isNull || err != nil {\n\t\treturn 0, isNull, errors.Trace(err)\n\t}\n\treturn int64(len([]byte(val))), false, nil\n}\n```\n\n**然后看 expression/builtin\\_string\\_test.go，对已有的 TestLength() 方法进行完善：**\n\n```go\nfunc (s *testEvaluatorSuite) TestLength(c *C) {\n\tdefer testleak.AfterTest(c)() // 监测 goroutine 泄漏的工具，可以直接照搬\n  \t// cases 的测试用例对 length 方法实现进行测试\n\t// 此处注意，除了正常 case 之外，最好能添加一些异常的 case，如输入值为 nil，或者是多种类型的参数\n\tcases := []struct {\n\t\targs     interface{}\n\t\texpected int64\n\t\tisNil    bool\n\t\tgetErr   bool\n\t}{\n\t\t{\"abc\", 3, false, false},\n\t\t{\"你好\", 6, false, false},\n\t\t{1, 1, false, false},\n\t\t...\n\t}\n\tfor _, t := range cases {\n\t\tf, err := newFunctionForTest(s.ctx, ast.Length, primitiveValsToConstants([]interface{}{t.args})...)\n\t\tc.Assert(err, IsNil)\n\t\t// 以下对 LENGTH 函数的返回值类型进行测试\n\t\ttp := f.GetType()\n\t\tc.Assert(tp.Tp, Equals, mysql.TypeLonglong)\n\t\tc.Assert(tp.Charset, Equals, charset.CharsetBin)\n\t\tc.Assert(tp.Collate, Equals, charset.CollationBin)\n\t\tc.Assert(tp.Flag, Equals, uint(mysql.BinaryFlag))\n\t\tc.Assert(tp.Flen, Equals, 10)\n\t\t// 以下对 LENGTH 函数的计算结果进行测试\n\t\td, err := f.Eval(nil)\n\t\tif t.getErr {\n\t\t\tc.Assert(err, NotNil)\n\t\t} else {\n\t\t\tc.Assert(err, IsNil)\n\t\t\tif t.isNil {\n\t\t\t\tc.Assert(d.Kind(), Equals, types.KindNull)\n\t\t\t} else {\n\t\t\t\tc.Assert(d.GetInt64(), Equals, t.expected)\n\t\t\t}\n\t\t}\n\t}\n\t// 以下测试函数是否是具有确定性\n\tf, err := funcs[ast.Length].getFunction([]Expression{Zero}, s.ctx)\n\tc.Assert(err, IsNil)\n\tc.Assert(f.isDeterministic(), IsTrue)\n}\n```\n\n\n\n**最后看 executor/executor_test.go，对 LENGTH 的实现进行 SQL 层面的测试：**\n\n\n```go\n// 关于 string built-in 函数的测试可以在这个方法中添加\nfunc (s *testSuite) TestStringBuiltin(c *C) {\n\tdefer func() {\n\t\ts.cleanEnv(c)\n\t\ttestleak.AfterTest(c)()\n\t}()\n\ttk := testkit.NewTestKit(c, s.store)\n\ttk.MustExec(\"use test\")\n\n\t// for length\n\t// 此处的测试最好也能覆盖多种不同的情况\n\ttk.MustExec(\"drop table if exists t\")\n\ttk.MustExec(\"create table t(a int, b double, c datetime, d time, e char(20), f bit(10))\")\n\ttk.MustExec(`insert into t values(1, 1.1, \"2017-01-01 12:01:01\", \"12:01:01\", \"abcdef\", 0b10101)`)\n\tresult := tk.MustQuery(\"select length(a), length(b), length(c), length(d), length(e), length(f), length(null) from t\")\n\tresult.Check(testkit.Rows(\"1 3 19 8 6 2 <nil>\"))\n}\n```\n\n\n## 重构前的表达式计算框架\n\nTiDB 通过 Expression 接口(在 expression/expression.go 文件中定义)对表达式进行抽象，并定义 eval 方法对表达式进行计算：\n\n\n```go\ntype Expression interface{\n    ...\n    eval(row []types.Datum) (types.Datum, error)\n    ...\n}\n```\n\n\n实现 Expression 接口的表达式包括：\n\n- Scalar Function：标量函数表达式\n- Column：列表达式\n- Constant：常量表达式\n\n下面以一个例子说明重构前的表达式计算框架。\n\n例如：\n\n\n```sql\ncreate table t (\n    c1 int,\n    c2 varchar(20),\n    c3 double\n)\n\nselect * from t where c1 + CONCAT( c2, c3 < “1.1” )\n```\n\n\n对于上述 select 语句 where 条件中的表达式：\n在**编译阶段**，TiDB 将构建出如下图所示的表达式树:\n\n![编译阶段表达式树 1](https://img1.www.pingcap.com/prod/1_61e0d8d199.jpg)\n\n在**执行阶段**，调用根节点的 eval 方法，通过后续遍历表达式树对表达式进行计算。\n\n对于表达式 ‘<’，计算时需要考虑两个参数的类型，并根据一定的规则，将两个参数的值转化为所需的数据类型后进行计算。上图表达式树中的 ‘<’，其参数类型分别为 double 和 varchar，根据 MySQL 的计算规则，此时需要使用浮点类型的计算规则对两个参数进行比较，因此需要将参数 “1.1” 转化为 double 类型，而后再进行计算。\n\n同样的，对于上图表达式树中的表达式 CONCAT，计算前需要将其参数分别转化为 string 类型；对于表达式 ‘+’，计算前需要将其参数分别转化为 double 类型。\n\n因此，在重构前的表达式计算框架中，对于参与运算的每一组数据，计算时都需要**大量的判断分支重复地对参数的数据类型进行判断**，若参数类型不符合表达式的运算规则，则需要将其转换为对应的数据类型。\n\n此外，由 Expression.eval() 方法定义可知，在运算过程中，需要**通过 Datum 结构不断地对中间结果进行包装和解包**，由此也会带来一定的时间和空间开销。\n\n为了解决这两点问题，我们对表达式计算框架进行重构。\n\n## 重构后的表达式计算框架\n\n重构后的表达式计算框架，一方面，在编译阶段利用已有的表达式类型信息，生成参数类型“符合运算规则”的表达式，从而保证在运算阶段中无需再对类型增加分支判断；另一方面，运算过程中只涉及原始类型数据，从而避免 Datum 带来的时间和空间开销。\n\n继续以上文提到的查询为例，在**编译阶段**，生成的表达式树如下图所示，对于不符合函数参数类型的表达式，为其加上一层 cast 函数进行类型转换；\n\n![编译阶段表达式树 2](https://img1.www.pingcap.com/prod/2_2f797df17a.jpg)\n\n\n这样，在**执行阶段**，对于每一个 ScalarFunction，可以保证其所有的参数类型一定是符合该表达式运算规则的数据类型，无需在执行过程中再对参数类型进行检查和转换。\n\n## 附录\n\n- 对于一个 built-in 函数，由于其参数个数、类型以及返回值类型的不同，可能会生成多个函数签名分别用来处理不同的情况。对于大多数 built-in 函数，其每个参数类型及返回值类型均确定，此时只需要生成一个函数签名。\n- 对于较为复杂的返回值类型推导规则，可以参考 CONCAT 函数的实现和测试。可以利用 MySQLWorkbench 工具运行查询语句 `select funcName(arg0, arg1, ...)` 观察 MySQL 的 built-in 函数在传入不同参数时的返回值数据类型。\n- 在 TiDB 表达式的运算过程中，只涉及 6 种运算类型(目前正在实现对 JSON 类型的支持)，分别是\n  1. int (int64)\n  2. real (float64)\n  3. decimal\n  4. string\n  5. Time\n  6. Duration\n  通过 WrapWithCastAsXX() 方法可以将一个表达式转换为对应的类型。\n- 对于一个函数签名，其返回值类型已经确定，所以定义时需要组合与该类型对应的 baseXXBuiltinFunc，并实现 evalXX() 方法。(XX 不超过上述 6 种类型的范围)\n\n\n---------------------------- 我是 AI 的分割线 ----------------------------------------\n\n回顾三月启动的《十分钟成为 TiDB Contributor 系列 | 添加內建函数》活动，在短短的时间内，我们收到了来自社区贡献的超过 200 条新建內建函数，这之中有很多是来自大型互联网公司的资深数据库工程师，也不乏在学校或是刚毕业在刻苦钻研分布式系统和分布式数据库的学生。\n\nTiDB Contributor Club 将大家聚集起来，我们互相分享、讨论，一起成长。\n\n感谢你的参与和贡献，在开源的道路上我们将义无反顾地走下去，和你一起。\n\n**成为 New Contributor 赠送限量版马克杯**的活动还在继续中，任何一个新加入集体的小伙伴都将收到我们充满了诚意的礼物，很荣幸能够认识你，也很高兴能和你一起坚定地走得更远。\n\n#### 成为 New Contributor 获赠限量版马克杯，马克杯获取流程如下：\n\n1. 提交 PR\n2. PR提交之后，请耐心等待维护者进行 Review。\n   - 目前一般在一到两个工作日内都会进行 Review，如果当前的 PR 堆积数量较多可能回复会比较慢。\n   - 代码提交后 CI 会执行我们内部的测试，你需要保证所有的单元测试是可以通过的。期间可能有其它的提交会与当前 PR 冲突，这时需要修复冲突。\n   - 维护者在 Review 过程中可能会提出一些修改意见。修改完成之后如果 reviewer 认为没问题了，你会收到 LGTM(looks good to me) 的回复。当收到两个及以上的 LGTM 后，该 PR 将会被合并。\n3. 合并 PR 后自动成为 Contributor，会收到来自 PingCAP Team 的感谢邮件，请查收邮件并填写领取表单\n   - 表单填写地址：[http://cn.mikecrm.com/01wE8tX](http://cn.mikecrm.com/01wE8tX)\n4. 后台 AI 核查 GitHub ID 及资料信息，确认无误后随即便快递寄出属于你的限量版马克杯\n5. 期待你分享自己参与开源项目的感想和经验，TiDB Contributor Club 将和你一起分享开源的力量\n\n\n了解更多关于 TiDB 的资料请登陆我们的官方网站：[https://pingcap.com](https://pingcap.com)\n\n加入 TiDB Contributor Club 请添加我们的 AI 微信：\n\n![二维码](https://img1.www.pingcap.com/prod/3_531af02722.jpg)  \n> 点击查看更多 [成为 Contributor 系列文章](https://pingcap.com/zh/blog/?tag=Contributor)","date":"2017-06-22","author":"徐怀宇","fillInMethod":"writeDirectly","customUrl":"reconstruct-built-in-function","file":null,"relatedBlogs":[]},{"id":"Blogs_141","title":"【Infra Meetup No.45】Rust in TiKV","tags":[],"category":{"name":"社区动态"},"summary":null,"body":">本文整理自 4 月 16 日 Rust 专场 Meetup 上，我司首席架构师唐刘同学的现场分享，共享给大家。enjoy~\n\nHello everyone, today I will talk about how we use Rust in TiKV.\n\nBefore we begin, let me introduce myself. My name is TangLiu, the Chief Architect of PingCAP. Before I joined PingCAP, I had worked at Kingsoft and Tencent. I love open source and have developed some projects like LedisDB, go-mysql, etc…\n\nAt first, I will explain the reason why we chose Rust to develop TiKV, then show you the architecture of TiKV briefly and the key technologies. In the end, I will introduce what we plan to do in the future.\n\n## What’s TiKV?\n\nAll right, let’s begin. First, what is TiKV. TiKV is a distributed Key-Value database with the following features:\n\n- **Geo-replication**: We use Raft and Placement Driver to replicate data geographically to guarantee data safety.\n\n- **Horizontal scalability**: We can add some nodes directly if we find that the rapidly growing data will soon exceed the system capacity.\n\n- **Consistent distributed transaction**: We use an optimized, two phase commit protocol, based on Google Percolator, to support distributed transactions. You can use “begin” to start a transaction, then do something, then use “commit” or “rollback” to finish the transaction.\n\n- **Coprocessor for distributed computing**: Just like HBase, we support a coprocessor framework to let user do computing in TiKV directly.\n\n- **Working with TiDB like Spanner with F1**: Using TiKV as a backend storage engine of TiDB, we can provide the best distributed relational database.\n\n## We need a language with…\n\nAs you see, TiKV has many powerful features. To develop these features, we also need a powerful programming language. The language should have:\n\n- **Fast speed**: We take the performance of TiKV very seriously, so we need a language which runs very fast at runtime.\n\n- **Memory safety**: As a program that is going to run for a long time, we don’t want to meet any memory problem, such as dangling pointer, memory leak, etc…\n\n- **Thread safety**: We must guarantee data consistency all the time, so any data race problem must be avoided.\n\n- **Binding C efficiency**: We depend on RocksDB heavily, so we must be able to call the RocksDB API as fast as we can, without any performance reduction.\n\n## Why not C++?\n\nTo develop a high performance service, C++ may be the best choice in most cases, but we didn’t choose it. We figured we might spend too much time avoiding the memory problem or the data race problem. Moreover, C++ has no official package manager and that makes the maintaining and compiling third dependences very troublesome and difficult, resulting in a long development cycle.\n\n## Why not Go?\n\nAt first, we considered using Go, but then gave up this idea. Go has GC which fixes many memory problems, but it might stop the running process sometimes. No matter how little time the stop takes, we can’t afford it. Go doesn’t solve the data race problem either. Even we can use double dash race in test or at runtime, this isn’t enough.\n\nBesides, although we can use Goroutine to write the concurrent logic easily, we still can’t neglect the runtime expenses of the scheduler. We met a problem a few days ago: we used multi goroutines to select the same context but found that the performance was terrible, so we had to use one sub context for one goroutine, then the performance became better.\n\nMore seriously, CGO has heavy expenses, but we need to call RocksDB API without delay. For the above reasons, we didn’t choose Go even this is the favorite language in our team.\n\n## So we turned to Rust… But Rust…\n\nRust is a system programming language, maintained by Mozilla. It is a very powerful language, however, you can see the curve, the learning curve is very very steep.\n\n![Rust](https://img1.www.pingcap.com/prod/1_1c5b2d0d26.png)\n\nI have been using many programming languages, like C++, Go, python, lua, etc. and Rust is the hardest language for me to master. In PingCAP, we will let the new colleague spend at least one month to learn Rust, to struggle with the compiling errors, and then to rise above it. This would never happen for Go.\n\nBesides, the compiling time is very long, even longer than C++. Each time when I type cargo build to start building TiKV, I can even do some pushups.\n\nAlthough Rust is around for a long time, it still lacks of libraries and tools, and some third projects have not been verified in production yet. These are all the risks for us. Most seriously, it is hard for us to find Rust programmer because only few know it in China, so we are always shorthanded.\n\n## Then, Why Rust?\n\nAlthough Rust has the above disadvantages, its advantages are attractive for us too. Rust is memory safe, so we don’t need to worry about memory leak, or dangling pointer any more.\n\nRust is thread safe, so there won’t be any data race problem. All the safety are guaranteed by compiler. So in most cases, when the compiling passes, we are sure that we can run the program safely.\n\nRust has no GC expenses, so we won’t meet the “stop the world” problem. Calling C through FFI is very fast, so we don’t worry the performance reduction when calling the RocksDB API. At last, Rust has an official package manager, crate, we can find many libraries and use them directly.\n\n**We made a hard but great decision: Use Rust!**\n\n## TiKV Timeline\n\n![TiKV Timeline](https://img1.www.pingcap.com/prod/2_573a54a128.jpg)\n\nHere you can see the TiKV timeline. We first began to develop TiKV January 1st, 2016, and made it open source on April 1st, 2016, and this is not a joke like Gmail at All April Fool’s Day. TiKV was first used in production in October, 2016, when we had not even released a beta version. In November, 2016, we released the first beta version; then RC1 in December, 2016, RC2 in February, this year. Later we plan to release RC3 in April and the first GA version in June.\n\nAs you can see, the development of TiKV is very fast and the released versions of TiKV are stable. Choosing Rust has already been proved a correct decision. Thanks, Rust.\n\n## TiKV Architecture\n\n![TiKV Architecture](https://img1.www.pingcap.com/prod/3_fe7fa6d26e.png)\n\nNow let’s go deep into TiKV. You can see from the TiKV architecture that the hierarchy of TiKV is clear and easy to understand.\n\nAt the bottom layer, TiKV uses RocksDB, a high performance, persistent Key-Value store, as the backend storage engine.\n\nThe next layer is Raft KV. TiKV uses the Raft to replicate data geographically. TiKV is designed to store tons of data which one Raft group can’t hold. So we split the data with ranges and use each range as an individual Raft group. We name this approach: Multi-Raft groups.\n\nTiKV provides a simple Key-Value API including SET, GET, DELETE to let user use it just as any distributed Key-Value storage. The upper layer also uses these to support advanced functions.\n\nAbove the Raft layer, it is MVCC. All the keys saved in TiKV must contain a globally unique timestamp, which is allocated by Placement Driver. TiKV uses it to support distributed transactions.\n\nOn the top layer, it is the KV and coprocessor API layer for handling client requests.\n\n## Multi-Raft\n\n![Multi-Raft](https://img1.www.pingcap.com/prod/4_e7298ff408.jpg)\n\nHere is an example of Multi-Raft.\n\nYou can see that there are four TiKV nodes. Within each store, we have several regions. Region is the basic unit of data movement and is replicated by Raft. Each region is replicated to three nodes. These three replicas of one Region make a Raft group.\n\n## Scale Out\n\n### Scale-out (initial state)\n\n![Scale-out (initial state)](https://img1.www.pingcap.com/prod/5_ca3bbd46b8.jpg)\n\nHere is an example of horizontal scalability. At first, we have four nodes, Node A has three regions, others have two regions.\n\nOf course, Node A is busier than other nodes, and we want to reduce its stress.\n\n### Scale-out (add new node)\n\n![Scale-out (add new node)](https://img1.www.pingcap.com/prod/6_2f563477b2.jpg)\n\nSo we add a new Node E, and begin to move the region 1 in Node A to Node E. But here we find that the leader of region 1 is in Node A, so we will first transfer the leader from Node A to Node B.\n\n### Scale-out (balancing)\n\n![Scale-out (balancing)-1](https://img1.www.pingcap.com/prod/7_1bb2886931.jpg)\n\nAfter that, the leader of region 1 is in Node B now, then we add a new replica of region 1 in Node E.\n\n![Scale-out (balancing)-2](https://img1.www.pingcap.com/prod/8_130a759547.jpg)\n\nThen we remove the replica of region 1 from Node A. All these are executed by the Placement Driver automatically. What we only need is to add node, if we find the system is busy. Very easy, right?\n\n## A simple write flow\n\n![simple write flow](https://img1.www.pingcap.com/prod/9_2357850432.jpg)\n\nHere is a simple write flow: when a client sends a write request to TiKV, TiKV first parses the protocol and then dispatches the request to the KV thread, then the KV thread executes some transaction logics and sends the request to Raft thread, after TiKV replicates the Raft log and applies it to RocksDB, the write request is finished.\n\n## Key technologies\n\nNow let’s move on to the key technologies:\n\nFor networking, we use a widely used protocol, Protocol Buffers, to serialize or unserialize data fastly.\n\nAt first, we used **MIO** to build up the network framework. Although MIO encapsulates low level network handling, it is still a very basic library that we need to receive or send data manually, and to decode or encode our customized network protocol. It is not convenient actually. So from RC2, we have been refactoring networking with gRPC. The benefit of gRPC is very obvious. We don’t need to care how to handle network anymore, only focusing on our logic, and the code looks simple and clear. Meanwhile, users can build their own TiKV client with other programming languages easily. We have already been developing a TiKV client with Java.\n\nFor **asynchronous framework**. After receiving the request, TiKV dispatches the request to different threads to handle it asynchronously. At first, we used the MIO plus callback to handle the asynchronous request, but callback may break the code logic, and it is hard to read and write correctly, so now we have been refactoring with tokio-core and futures, and we think this style is more modern for Rust in the future. Sometimes, we also use the thread pool to dispatch simple tasks, and we will use futures-cpupool later.\n\nFor **storage**, we use rust-rocksdb to access RocksDB.\n\nFor **monitoring**, we wrote a rust client for Prometheus, and this client is recommended in the official wiki. For profiling, we use the jemallocator with enabling profile feature and use clippy to check our codes.\n\n## Future plan\n\nOk, that’s what we have done and are doing. Here are what we will do in the future:\n\n- Make TiKV faster, like removing Box. we have used many boxes in TiKV to write code easily, this is not efficient. In our benchmark, dynamic dispatch is at least three times slower than static dispatch, so later we will use Trait Trait directly.\n\n- Make TiKV more stable, like introducing Rust sanitizer.\n\n- Contribute more Rust open source modules, like raft library, open-tracing, etc.\n\n- Participate in other Rust projects more deeply, like rust-gRPC\n\n- Write more articles about Rust on Chinese social media and organize more Rust meetups.\n\n- Be a strong advocate of Rust in China.\n\n![合影](https://img1.www.pingcap.com/prod/10_d298043465.jpg)","date":"2017-05-31","author":"唐刘","fillInMethod":"writeDirectly","customUrl":"rust-in-tikv","file":null,"relatedBlogs":[]},{"id":"Blogs_223","title":"如何从零开始参与大型开源项目","tags":["开源","社区"],"category":{"name":"社区动态"},"summary":"我们欢迎所有的具有气质的开发者能和 TiDB 一起成长，一起见证数据库领域的革新，改变世界这事儿有时候也不那么难。","body":"## 写在前面的话\n\n上世纪 70 年代，IBM 发明了关系型数据库。但是随着现在移动互联网的发展，接入设备越来越多，数据量越来越大，业务越来越复杂，传统的数据库显然已经不能满足海量数据存储的需求。虽然目前市场上也不乏分布式数据库模型，但没有品位的文艺青年不是好工程师，我们觉得，不，这些方案都不是我们想要的，它们不够美，鲜少能够把分布式事务与弹性扩展做到完美。\n\n受 Google Spanner/F1 的启发，一款从一开始就选择了开源道路的 TiDB 诞生了。 它是一款代表未来的新型分布式 NewSQL 数据库，它可以随着数据增长而无缝水平扩展，只需要通过增加更多的机器来满足业务增长需求，应用层可以不用关心存储的容量和吞吐，用东旭的话说就是「他自己会生长」。\n\n在开源的世界里，TiDB 和 TiKV 吸引了更多的具有极客气质的开发者，目前已经拥有超过 9000 个 star 和 100 个 Contributor，这已然是一个世界顶级开源项目的水准。而成就了这一切的，则是来自社区的力量。\n\n最近我们收到了很多封这样的邮件和留言，大家说：\n\n- “谢谢你们，使得旁人也能接触大型开源项目。本身自己是 DBA，对数据库方面较感兴趣，也希望自己能逐步深入数据库领域，深入TiDB，为 TiDB 社区贡献更多、更有价值的力量。”\n\n- “我是一个在校学生，刚刚收到邮件说我成为了 TiDB 的 Contributor，这让我觉得当初没听父母的话坚持了自己喜欢的计算机技术，是个正确的选择，但我还需要更多的历练，直到能完整地展现、表达我的思维。”\n\n这让我感触颇多，因为，应该是我们感谢你们才是啊，没有社区，一个开源项目就成不了一股清泉甚至一汪海洋。\n\n公司的小姑娘说，她觉得还有很多的人想要参与进来的，可工程师团队欠缺平易近人的表达，这个得改。\n\n于是便有了这篇文章以及未来的多篇文章和活动，我们欢迎所有的具有气质的开发者能和 TiDB 一起成长，一起见证数据库领域的革新，改变世界这事儿有时候也不那么难。\n\n我要重点感谢今天这篇文章的作者，来自社区的朱武（GitHub ID: viile ）、小卢（GitHub ID: lwhhhh ）和杨文（GitHub ID: yangwenmai），当在 TiDB Contributor Club 里提到想要做这件事的时候，是他们踊跃地加入了 TiDB Tech Writer 的队伍，高效又专业地完成了下文的编辑，谢谢你们。\n\n## 一个典型的开源项目是由什么组成的\n\n### The Community（社区）\n\n- 一个项目经常会有一个围绕着它的社区，这个社区由各个承担不同角色的用户组成。\n\n- **项目的拥有者**：在他们账号中创建项目并拥有它的用户或者组织。\n\n- **维护者和合作者**：主要做项目相关的工作和推动项目发展，通常情况下拥有者和维护者是同一个人，他们拥有仓库的写入权限。\n\n- **贡献者**：发起拉取请求（pull request）并且被合并到项目里面的人。\n\n- **社区成员**：对项目非常关心，并且在关于项目的特性以及 pull requests 的讨论中非常活跃的人。\n\n### The Docs（文档）\n\n项目中经常出现的文件有：\n\n- **Readme**：几乎所有的 Github 项目都包含一个 README\\.md 文件，readme 文件提供了一些项目的详细信息，包括如何使用，如何构建。有时候也会告诉你如何成为贡献者。\n  - [TiDB README](https://github.com/pingcap/tidb/blob/master/README.md)\n\n- **Contributing**：项目以及项目的维护者各式各样，所以参与贡献的最佳方式也不尽相同。如果你想成为贡献者的话，那么你要先阅读那些有 CONTRIBUTING 标签的文档。Contributing 文档会详细介绍了项目的维护者希望得到哪些补丁或者是新增的特性。\n\n  文件里也可以包含需要写哪些测试，代码风格，或者是哪些地方需要增加补丁之类的内容。\n  \n  - [TiDB Contributing 文档](https://github.com/pingcap/tidb/blob/master/CONTRIBUTING.md)\n\n- **License**：LICENSE 文件就是这个开源项目的许可证。一个开源项目会告知用户他们可以做什么，不可做什么(比如：使用，修改，重新分发)，以及贡献者允许其他人做哪些事。开源许可证有多种，你可以在 [认识各种开源协议及其关系](http://www.ruanyifeng.com/blog/2011/05/how_to_choose_free_software_licenses.html) 了解更多关于开源许可证的信息。\n  - TiDB 遵循 [Apache-2.0 License](https://github.com/pingcap/tidb/blob/master/LICENSE)\n  - TiKV 遵循 [Apache-2.0 License](https://github.com/pingcap/tikv/blob/master/LICENSE)\n\n-  **Documentation**：许多大型项目不会只通过自述文件去引导用户如何使用。在这些项目中你经常可以找到通往其他文件的超链接，或者是在仓库中找到一个叫做 docs 的文件夹.\n  - [TiDB Docs](https://github.com/pingcap/tidb/tree/master/docs)\n \n  ![TiDB Docs](https://img1.www.pingcap.com/prod/1_92161b214a.jpg)\n  \n  <div class=\"caption-center\">TiDB Docs</div>\n\n\n## 齐步走成为 Contributor\n\n### Create an Issue\n\n如果你在使用项目中发现了一个 bug，而且你不知道怎么解决这个 bug。或者使用文档时遇到了麻烦。或者有关于这个项目的问题。你可以创建一个 issue。\n\n不管你有什么 bug，你提出 bug 后，会对那些和你有同样 bug 的人提供帮助。\n更多关于 issue 如何工作的信息，请点击 [Issues guide](http://guides.github.com/features/issues)。\n\n\n#### Issues Pro Tips\n\n* **检查你的问题是否已经存在**  重复的问题会浪费大家的时间，所以请先搜索打开和已经关闭的问题，来确认你的问题是否已经提交过了。\n\n* **清楚描述你的问题**\n\n    TiDB Issue 模版如下：\n\n    ![TiDB Issue 模版](https://img1.www.pingcap.com/prod/2_2522aff338.png)\n    \n    <div class=\"caption-center\">TiDB Issue 模版</div>\n\n    TiKV Issue 模版如下：\n    \n    ![TiKV Issue 模版](https://img1.www.pingcap.com/prod/3_eb48a0d369.png)\n    \n    <div class=\"caption-center\">TiKV Issue 模版</div>\n\n* **给出你的代码链接** 使用像 [JSFiddle](http://jsfiddle.net/) 或者 [CodePen](http://codepen.io/) 等工具，贴出你的代码，好帮助别人复现你的问题。\n\n* **详细的系统环境介绍** 例如使用什么版本的浏览器，什么版本的库，什么版本的操作系统等其他你运行环境的介绍。\n\n  ```\n  go 版本： go version\n  Linux 版本： uname -a\n  ```\n\n* **详细的错误输出或者日志** 使用 [Gist](http://gist.github.com/) 贴出你的错误日志。如果你在 issue 中附带错误日志，请使用 ``` 来标记你的日志。以便更好的显示。\n\n### Pull Request\n\n如果你能解决这个 bug，或者你能够添加其他的功能。并且知道如何成为贡献者，理解 license，已经签过 [Contributor License Agreement](https://en.wikipedia.org/wiki/Contributor_License_Agreement)（CLA）后，请发起 Pull Request。这样维护人员可以将你的分支与现有分支进行比较，来决定是否合并你的更改。\n\n### Pull Request Pro Tips\n\n* **[Fork](http://guides.github.com/activities/forking/) 代码并且 clone 到你本地** 通过将项目的地址添加为一个 remote，并且经常从 remote 合并更改来保持你的代码最新，以便在提交你的 pull 请求时，尽可能少的发生冲突。详情请参阅 [Syncing a fork](https://help.github.com/articles/syncing-a-fork)。\n\n* **创建 [branch](http://guides.github.com/introduction/flow/)** 来修改你的代码，目前 TiDB 相关的项目默认的 branch 命名规则是 user/name。例如 disksing/grpc，简单明确，一目了然。\n\n* **描述清楚你的问题**方便其他人能够复现。或者说明你添加的功能有什么作用，并且清楚描述你做了哪些更改。\n\n* **注意测试** 如果项目中包含逻辑修改，那么必须包含相应的测试，在 CI 中会包含测试覆盖率的检测，如果测试覆盖率下降，那么是不可以合并到 master 的。\n\n* **包含截图** 如果您的更改包含 HTML/CSS 中的差异，请添加前后的屏幕截图。将图像拖放到您的 pull request 的正文中。\n\n* **保持良好的代码风格**这意味着使用与你自己的代码风格中不同的缩进，分号或注释，但是使维护者更容易合并，其他人将来更容易理解和维护。目前 TiDB 项目的 CI 检测包含代码风格的检查，如果代码风格不符合要求，那么是不可以合并到 master 的。\n\n### Open Pull Requests\n\n一旦你新增一个 pull request，讨论将围绕你的更改开始。其他贡献者和用户可能会进入讨论，但最终决定是由维护者决定的。你可能会被要求对你的 pull request 进行一些更改，如果是这样，请向你的 branch 添加更多代码并推送它们，它们将自动进入现有的 pull request。\n\n![Open Pull Requests](https://img1.www.pingcap.com/prod/4_86f1bc587c.png)\n\n<div class=\"caption-center\">Open Pull Requests</div>\n\n如果你的 pull request 被合并，这会非常棒。如果没有被合并，不要灰心。也许你的更改不是项目维护者需要的。或者更改已经存在了。发生这种情况时，我们建议你根据收到的任何反馈来修改代码，并再次提出 pull request。或创建自己的开源项目。\n\n### TiDB 合并流程\n\nPR 提交之后，请耐心等待维护者进行 Review。\n\n目前一般在一到两个工作日内都会进行 Review，如果当前的 PR 堆积数量较多可能回复会比较慢。\n代码提交后 CI 会执行我们内部的测试，你需要保证所有的单元测试是可以通过的。期间可能有其它的提交会与当前 PR 冲突，这时需要修复冲突。\n\n维护者在 Review 过程中可能会提出一些修改意见。修改完成之后如果 reviewer 认为没问题了，你会收到 LGTM（looks good to me）的回复。当收到两个及以上的 LGTM 后，该 PR 将会被合并。\n\n>标注：本文「一个典型的开源项目是由什么组成的」及「齐步走为 Contributor」参考自英文 GitHub Guide，由社区成员朱武（GitHub ID: viile）、小卢（GitHub ID:lwhhhh）着手翻译并替换部分原文中的截图。GitHub Guides：如何参与一个 GitHub 开源项目 [英文原文](https://guides.github.com/activities/contributing-to-open-source/)。\n\n**加入 TiDB Contributor Club**\n\n为更好地促进 Contributor 间的交流，便于随时提出好的想法和反馈，我们创建了一个 Contributor Club 微信群，对成为 TiDB Contributor 有兴趣的同学可以添加 TiDB Robot 微信号，它会在后台和你打招呼，并积极招募你成为开源社区的一员。\n\n![二维码](https://img1.www.pingcap.com/prod/5_e48d933ff7.jpg)","date":"2017-03-27","author":"TiDB Contributor","fillInMethod":"writeDirectly","customUrl":"how-to-contribute","file":null,"relatedBlogs":[]},{"id":"Blogs_38","title":"十分钟成为 TiDB Contributor 系列 | 添加內建函数","tags":["TiDB","Contributor","内建函数","社区"],"category":{"name":"社区动态"},"summary":"最近我们对 TiDB 代码做了些改进，大幅度简化了添加內建函数的流程，这篇教程描述如何为 TiDB 新增 builtin 函数。首先介绍一些必需的背景知识，然后介绍增加 builtin 函数的流程，最后会以一个函数作为示例。","body":"## **背景知识**\n\nSQL 语句发送到 TiDB 后首先会经过 parser，从文本 parse 成为 AST（抽象语法树），通过 Query Optimizer 生成执行计划，得到一个可以执行的 plan，通过执行这个 plan 即可得到结果，这期间会涉及到如何获取 table 中的数据，如何对数据进行过滤、计算、排序、聚合、滤重以及如何对表达式进行求值。\n对于一个 builtin 函数，比较重要的是进行语法解析以及如何求值。其中语法解析部分需要了解如何写 yacc 以及如何修改 TiDB 的词法解析器，较为繁琐，我们已经将这部分工作提前做好，大多数 builtin 函数的语法解析工作已经做完。\n对 builtin 函数的求值需要在 TiDB 的表达式求值框架下完成，每个 builtin 函数被认为是一个表达式，用一个 ScalarFunction 来表示，每个 builtin 函数通过其函数名以及参数，获取对应的函数类型以及函数签名，然后通过函数签名进行求值。\n总体而言，上述流程对于不熟悉 TiDB 的朋友而言比较复杂，我们对这部分做了些工作，将一些流程性、较为繁琐的工作做了统一处理，目前已经将大多数未实现的 buitlin 函数的语法解析以及寻找函数签名的工作完成，但是函数实现部分留空。***换句话说，只要找到留空的函数实现，将其补充完整，即可作为一个 PR。***\n\n## **添加 builtin 函数整体流程**\n\n1. 找到未实现的函数\n\n    在 TiDB 源码中的 expression 目录下搜索 `errFunctionNotExists`，即可找到所有未实现的函数，从中选择一个感兴趣的函数，比如 SHA2 函数：\n\n    ```\n    func (b *builtinSHA2Sig) eval(row []types.Datum) (d types.Datum, err error) {\n    return d, errFunctionNotExists.GenByArgs(\"SHA2\")\n    }\n    ```\n\n2. 实现函数签名\n\n    接下来要做的事情就是实现 eval 方法，函数的功能请参考 MySQL 文档，具体的实现方法可以参考目前已经实现函数。\n\n3. 在 typeinferer 中添加类型推导信息\n\n    在 plan/typeinferer.go 中的 handleFuncCallExpr() 里面添加这个函数的返回结果类型，请保持和 MySQL 的结果一致。全部类型定义参见 [MySQL Const](https://github.com/pingcap/tidb/blob/source-code/mysql/type.go#L17)。\n\n    > **注意**：大多数函数除了需要填写返回值类型之外，还需要获取返回值的长度。\n\n4. 写单元测试\n\n    在 expression 目录下，为函数的实现增加单元测试，同时也要在 plan/typeinferer_test.go 文件中添加 typeinferer 的单元测试\n\n5. 运行 make dev，确保所有的 test case 都能跑过。\n\n## **示例**\n\n这里以[新增 SHA1() 函数的 PR](https://github.com/pingcap/tidb/pull/2781/files) 为例，进行详细说明\n\n1. 首先看 `expression/builtin_encryption.go`：\n将 SHA1() 的求值方法补充完整\n\n    ```\n    func (b *builtinSHA1Sig) eval(row []types.Datum) (d types.Datum, err error) {\n        // 首先对参数进行求值，这块一般不用修改\n        args, err := b.evalArgs(row)\n        if err != nil {\n            return types.Datum{}, errors.Trace(err)\n        }\n        // 每个参数的意义请参考 MySQL 文档\n        // SHA/SHA1 function only accept 1 parameter\n        arg := args[0]\n        if arg.IsNull() {\n            return d, nil\n        }\n        // 这里对参数值做了一个类型转换，函数的实现请参考 util/types/datum.go\n        bin, err := arg.ToBytes()\n        if err != nil {\n            return d, errors.Trace(err)\n        }\n        hasher := sha1.New()\n        hasher.Write(bin)\n        data := fmt.Sprintf(\"%x\", hasher.Sum(nil))\n        // 设置返回值\n        d.SetString(data)\n        return d, nil\n    }\n    ```\n\n2. 接下来给函数实现添加单元测试，参见 `expression/builtin_encryption_test.go`：\n\n    ```\n    var shaCases = []struct {\n        origin interface{}\n        crypt  string\n     }{\n        {\"test\", \"a94a8fe5ccb19ba61c4c0873d391e987982fbbd3\"},\n        {\"c4pt0r\", \"034923dcabf099fc4c8917c0ab91ffcd4c2578a6\"},\n        {\"pingcap\", \"73bf9ef43a44f42e2ea2894d62f0917af149a006\"},\n        {\"foobar\", \"8843d7f92416211de9ebb963ff4ce28125932878\"},\n        {1024, \"128351137a9c47206c4507dcf2e6fbeeca3a9079\"},\n        {123.45, \"22f8b438ad7e89300b51d88684f3f0b9fa1d7a32\"},\n     }\n\n     func (s *testEvaluatorSuite) TestShaEncrypt(c *C) {\n        defer testleak.AfterTest(c)() // 监测 goroutine 泄漏的工具，可以直接照搬\n        fc := funcs[ast.SHA]\n        for _, test := range shaCases {\n            in := types.NewDatum(test.origin)\n            f, _ := fc.getFunction(datumsToConstants([]types.Datum{in}), s.ctx)\n            crypt, err := f.eval(nil)\n            c.Assert(err, IsNil)\n            res, err := crypt.ToString()\n            c.Assert(err, IsNil)\n            c.Assert(res, Equals, test.crypt)\n        }\n        // test NULL input for sha\n        var argNull types.Datum\n        f, _ := fc.getFunction(datumsToConstants([]types.Datum{argNull}), s.ctx)\n        crypt, err := f.eval(nil)\n        c.Assert(err, IsNil)\n        c.Assert(crypt.IsNull(), IsTrue)\n    }\n    ```\n    \n    > **注意**：除了正常 case 之外，最好能添加一些异常的case，如输入值为 nil，或者是多种类型的参数\n    \n3. 最后还需要添加类型推导信息以及 test case，参见 `plan/typeinferer.go`，`plan/typeinferer_test.go`：\n\n    ```\n    case ast.SHA, ast.SHA1:\n            tp = types.NewFieldType(mysql.TypeVarString)\n            chs = v.defaultCharset\n            tp.Flen = 40\n    ```\n    \n    ```\n            {`sha1(123)`, mysql.TypeVarString, \"utf8\"},\n            {`sha(123)`, mysql.TypeVarString, \"utf8\"},\n    ```\n\n\n编辑按：添加 TiDB Robot 微信，加入 TiDB Contributor Club，无门槛参与开源项目，改变世界从这里开始吧（萌萌哒）。\n\n![二维码](https://img1.www.pingcap.com/prod/tidb_robot_b10949d1a7.jpg)  \n\n> 点击查看更多 [成为 Contributor 系列文章](https://pingcap.com/zh/blog/?tag=Contributor)","date":"2017-03-14","author":"申砾","fillInMethod":"writeDirectly","customUrl":"add-a-built-in-function","file":null,"relatedBlogs":[]}],"blogCategories":[{"name":"产品技术解读"},{"name":"公司动态"},{"name":"社区动态"},{"name":"案例实践"},{"name":"观点洞察"}],"blogRecommend":[{"blog":{"author":"黄东旭","summary":"PingCAP 联合创始人兼 CTO 黄东旭分介绍了 TiDB Serverless 作为未来一代数据库的核心设计理念，同时探讨了 TiDB Serverless 对于中国用户的价值。","title":"黄东旭：The Future of Database，掀开 TiDB Serverless 的引擎盖","date":"2023-07-24","customUrl":"the-future-of-database-2023"}},{"blog":{"author":"张翔","summary":"本次分享在介绍 Serverless Tier 的技术细节之余，全面解析了 TiDB 的技术生态全景和在生态构建中所做的努力。阅读本文，了解有关 Serverless 的更多信息，以及 PingCAP 在技术领域的最新进展。","title":"TiDB Serverless 和技术生态全景","date":"2023-02-20","customUrl":"tidb-serverless-and-technology-ecology-overview"}},{"blog":{"author":"韩锋","summary":"本文转载自公众号：韩锋频道（hanfeng_channel）。文章从金融用户角度入手，对如何选择分布式数据库及选型后的最优实践进行了阐述。","title":"金融业分布式数据库选型及 HTAP 场景实践","date":"2022-05-19","customUrl":"distributed-database-selection-and-htap-practice-in-financial-industry"}},{"blog":{"author":"黄东旭","summary":"很多时候「品味」之所以被称为「品味」，就是因为说不清道不明，这固然是软件开发艺术性的一种体现，但是这也意味着它不可复制，不易被习得。本系列文章会试着总结一下好的基础软件体验到底从哪里来。作为第一篇，本文将围绕可观测性和可交互性两个比较重要的话题来谈。","title":"做出让人爱不释手的基础软件：可观测性和可交互性","date":"2021-10-15","customUrl":"how-to-develop-an-infrasoft-observability-and-interactivity"}},{"blog":{"author":"刘奇","summary":"我们更多时候是站在哲学层面思考整个公司的运转和 TiDB 这个产品的演进的思路。这些思路很多时候是大家看不见的，因为不是一个纯粹的技术层面或者算法层面的事情。","title":"势高，则围广：TiDB 的架构演进哲学","date":"2019-05-30","customUrl":"guiding-ideologies-in-the-evolution-of-tidb"}}],"blogMostPopular":[{"blog":{"author":"申砾","customUrl":"tidb-internal-1","date":"2017-05-15","summary":"数据库、操作系统和编译器并称为三大系统，可以说是整个计算机软件的基石。其中数据库更靠近应用层，是很多业务的支撑。这一领域经过了几十年的发展，不断的有新的进展。很多人用过数据库，但是很少有人实现过一个数据库，特别是实现一个分布式数据库。了解数据库的实现原理和细节，一方面可以提高个人技术，对构建其他系统有帮助，另一方面也有利于用好数据库。研究一门技术最好的方法是研究其中一个开源项目，数据库也不例外。单机数据库领域有很多很好的开源项目，其中 MySQL 和 PostgreSQL 是其中知名度最高的两个，不少同学都看过这两个项目的代码。但是分布式数据库方面，好的开源项目并不多。 TiDB 目前获得了广泛的关注，特别是一些技术爱好者，希望能够参与这个项目。由于分布式数据库自身的复杂性，很多人并不能很好的理解整个项目，所以我希望能写一些文章，自顶向下，由浅入深，讲述 TiDB 的一些技术原理，包括用户可见的技术以及大量隐藏在 SQL 界面后用户不可见的技术点。","title":"三篇文章了解 TiDB 技术内幕 - 说存储"}},{"blog":{"author":"申砾","customUrl":"tidb-internal-2","date":"2017-05-24","summary":"上一篇介绍了 TiDB 如何存储数据，也就是 TiKV 的一些基本概念。本篇将介绍 TiDB 如何利用底层的 KV 存储，将关系模型映射为 Key-Value 模型，以及如何进行 SQL 计算。","title":"三篇文章了解 TiDB 技术内幕 - 说计算"}},{"blog":{"author":"申砾","customUrl":"tidb-internal-3","date":"2017-06-06","summary":"任何一个复杂的系统，用户感知到的都只是冰山一角，数据库也不例外。前两篇文章介绍了 TiKV、TiDB 的基本概念以及一些核心功能的实现原理，这两个组件一个负责 KV 存储，一个负责 SQL 引擎，都是大家看得见的东西。在这两个组件的后面，还有一个叫做 PD（Placement Driver）的组件，虽然不直接和业务接触，但是这个组件是整个集群的核心，负责全局元信息的存储以及 TiKV 集群负载均衡调度。本篇文章介绍一下这个神秘的模块。这部分比较复杂，很多东西大家平时不会想到，也很少在其他文章中见到类似的东西的描述。我们还是按照前两篇的思路，先讲我们需要什么样的功能，再讲我们如何实现，大家带着需求去看实现，会更容易的理解我们做这些设计时背后的考量。","title":"三篇文章了解 TiDB 技术内幕 - 谈调度"}},{"blog":{"author":"PingCAP","customUrl":"introduction-of-open-source-license","date":"2021-10-20","summary":"PingCAP 从第一行代码开源，六年里积累了一些经验和教训，在《开源知识科普》栏目中，我们将与大家分享和交流在开源成长路径中的思考和感受，以及参与开源项目的正确姿势。本期话题就从开源的基础——开源许可证开始，希望对大家了解开源、参与开源有一定帮助。","title":"一文看懂开源许可证丨开源知识科普"}},{"blog":{"author":"唐刘","customUrl":"grpc","date":"2017-06-18","summary":"经过很长一段时间的开发，TiDB 终于发了 RC3。RC3 版本对于 TiKV 来说最重要的功能就是支持了 gRPC，也就意味着后面大家可以非常方便的使用自己喜欢的语言对接 TiKV 了。gRPC 是基于 HTTP/2 协议的，要深刻理解 gRPC，理解下 HTTP/2 是必要的，这里先简单介绍一下 HTTP/2 相关的知识，然后再介绍下 gRPC 是如何基于 HTTP/2 构建的。","title":"深入了解 gRPC：协议"}}],"allTags":[{"name":"TiDB","count":179},{"name":"社区","count":103},{"name":"TiKV","count":30},{"name":"社区动态","count":29},{"name":"TiDB 源码阅读","count":24},{"name":"TiKV 源码解析","count":21},{"name":"HTAP","count":20},{"name":"Release","count":17},{"name":"TiFlash","count":16},{"name":"Chaos Mesh","count":15},{"name":"TiDB Hackathon 2021","count":13},{"name":"Raft","count":11},{"name":"TiCDC","count":11},{"name":"TiDB 4.0 新特性","count":11},{"name":"DM 源码阅读","count":10},{"name":"Contributor","count":9},{"name":"TiDB Binlog 源码阅读","count":9},{"name":"TiFlash 源码阅读","count":9},{"name":"TiDB Hackathon 2022","count":8},{"name":"技术出海","count":8},{"name":"Serverless","count":7},{"name":"TiDB Hackathon 2020","count":7},{"name":"TiDB 性能调优","count":7},{"name":"分布式数据库","count":7},{"name":"DM","count":6},{"name":"SQL","count":6},{"name":"最佳实践","count":6},{"name":"架构","count":6},{"name":"Hackathon","count":5},{"name":"PD","count":5},{"name":"Rust","count":5},{"name":"TiDB Binlog","count":5},{"name":"TiDB Cloud","count":5},{"name":"TiDB Operator","count":5},{"name":"TiDB Operator 源码阅读","count":5},{"name":"TiSpark","count":5},{"name":"事务","count":5},{"name":"事务前沿研究","count":5},{"name":"新经济 DTC 转型","count":5},{"name":"DevCon","count":4},{"name":"Linux","count":4},{"name":"MySQL","count":4},{"name":"TiDB 易用性挑战赛","count":4},{"name":"TiKV 功能介绍","count":4},{"name":"分布式系统前沿技术","count":4},{"name":"备份恢复","count":4},{"name":"大促背后的数据库","count":4},{"name":"工具","count":4},{"name":"性能","count":4},{"name":"数据迁移","count":4},{"name":"Committer","count":3},{"name":"Go","count":3},{"name":"Kubernetes","count":3},{"name":"Percolator","count":3},{"name":"PingCAP 用户峰会","count":3},{"name":"Prometheus","count":3},{"name":"RocksDB","count":3},{"name":"TiDB Ecosystem Tools","count":3},{"name":"TiDB Serverless","count":3},{"name":"TiKV 源码阅读","count":3},{"name":"云原生","count":3},{"name":"分布式系统测试","count":3},{"name":"基础软件","count":3},{"name":"BR","count":2},{"name":"Cloud-TiDB","count":2},{"name":"Dumpling","count":2},{"name":"Flink","count":2},{"name":"K8s","count":2},{"name":"Key Visualizer","count":2},{"name":"MVCC","count":2},{"name":"PingCAP","count":2},{"name":"PingCAP  用户峰会","count":2},{"name":"Spanner","count":2},{"name":"TiDB 性能挑战赛","count":2},{"name":"TiDB-4.0","count":2},{"name":"TiUP","count":2},{"name":"WebAssembly","count":2},{"name":"gRPC","count":2},{"name":"优化器","count":2},{"name":"升级","count":2},{"name":"多业务融合","count":2},{"name":"带着问题读 TiDB 源码","count":2},{"name":"性能优化","count":2},{"name":"性能调优","count":2},{"name":"数据同步","count":2},{"name":"版本","count":2},{"name":"资源管控","count":2},{"name":"集群调度","count":2},{"name":"2PC","count":1},{"name":"AI","count":1},{"name":"Ansible","count":1},{"name":"CAP","count":1},{"name":"Chat2Query","count":1},{"name":"ChatGPT","count":1},{"name":"Cloud","count":1},{"name":"DNB","count":1},{"name":"Data Platform","count":1},{"name":"Database","count":1},{"name":"Database Branching","count":1},{"name":"Elasticsearch","count":1},{"name":"Failpoint","count":1},{"name":"Fintech","count":1},{"name":"Flink TiDB 物化视图","count":1},{"name":"GA","count":1},{"name":"Grafana","count":1},{"name":"HAProxy","count":1},{"name":"HTAP TiFlash","count":1},{"name":"Hadoop","count":1},{"name":"Horoscope","count":1},{"name":"Jepsen","count":1},{"name":"Kudu","count":1},{"name":"LSM-tree","count":1},{"name":"Lease Read","count":1},{"name":"Libbpf-tools","count":1},{"name":"Linearizability","count":1},{"name":"MPP","count":1},{"name":"Multi-Raft","count":1},{"name":"MySQL 架构演进","count":1},{"name":"NewSQL","count":1},{"name":"OpenAI","count":1},{"name":"OpenSource","count":1},{"name":"Oracle 迁移","count":1},{"name":"Partitioned Raft KV","count":1},{"name":"Partitioned-Raft-KV","count":1},{"name":"PiTR","count":1},{"name":"Redis","count":1},{"name":"Resource Control","count":1},{"name":"SMP","count":1},{"name":"SQL Plan Management","count":1},{"name":"SaaS","count":1},{"name":"Spark","count":1},{"name":"Syncer","count":1},{"name":"THP","count":1},{"name":"Talent Plan","count":1},{"name":"Test","count":1},{"name":"The Future of Database","count":1},{"name":"TiDB + Flink","count":1},{"name":"TiDB 4.0","count":1},{"name":"TiDB 4.0 捉虫竞赛","count":1},{"name":"TiDB Dashboard","count":1},{"name":"TiDB DevCon 2020","count":1},{"name":"TiDB Hackathon 2023","count":1},{"name":"TiDB 工具","count":1},{"name":"TiDB-DM","count":1},{"name":"TiDB-Lightning","count":1},{"name":"TiEM","count":1},{"name":"TiKV 性能优化","count":1},{"name":"TiPocket","count":1},{"name":"Tile","count":1},{"name":"Titan","count":1},{"name":"Tools","count":1},{"name":"futures","count":1},{"name":"java","count":1},{"name":"k8s","count":1},{"name":"knossos","count":1},{"name":"一致性","count":1},{"name":"主从","count":1},{"name":"全文检索","count":1},{"name":"内建函数","count":1},{"name":"分布式","count":1},{"name":"分布式SQL","count":1},{"name":"分布式事务","count":1},{"name":"分布式计算","count":1},{"name":"历史读","count":1},{"name":"可串行化","count":1},{"name":"合作伙伴生态","count":1},{"name":"在线 DDL","count":1},{"name":"垃圾回收","count":1},{"name":"备份","count":1},{"name":"多版本并发控制","count":1},{"name":"多租户","count":1},{"name":"大数据","count":1},{"name":"存储","count":1},{"name":"存储引擎","count":1},{"name":"安装部署","count":1},{"name":"容灾机制","count":1},{"name":"工程实践","count":1},{"name":"平凯数据库","count":1},{"name":"应用场景","count":1},{"name":"开源","count":1},{"name":"开源知识科普","count":1},{"name":"异构复制","count":1},{"name":"性能挑战赛","count":1},{"name":"悲观锁","count":1},{"name":"持续性能分析","count":1},{"name":"数字化转型","count":1},{"name":"数据分片","count":1},{"name":"数据库","count":1},{"name":"无锁快照","count":1},{"name":"智能制造","count":1},{"name":"服务可观察","count":1},{"name":"机器学习","count":1},{"name":"查询优化","count":1},{"name":"核心批量核算","count":1},{"name":"水平扩展","count":1},{"name":"测试","count":1},{"name":"测试工具","count":1},{"name":"混沌工程","count":1},{"name":"源码分析","count":1},{"name":"版本迁移","count":1},{"name":"用户实践","count":1},{"name":"监控","count":1},{"name":"线性一致","count":1},{"name":"自动化","count":1},{"name":"自动化测试","count":1},{"name":"计算","count":1},{"name":"调优","count":1},{"name":"调度","count":1},{"name":"跨数据中心","count":1},{"name":"运维","count":1},{"name":"金融","count":1},{"name":"隔离级别","count":1},{"name":"高并发","count":1}],"hotTags":[{"name":"TiDB","count":179},{"name":"社区","count":103},{"name":"TiKV","count":30},{"name":"社区动态","count":29},{"name":"TiDB 源码阅读","count":24},{"name":"TiKV 源码解析","count":21},{"name":"HTAP","count":20},{"name":"Release","count":17},{"name":"TiFlash","count":16},{"name":"Chaos Mesh","count":15},{"name":"TiDB Hackathon 2021","count":13},{"name":"Raft","count":11},{"name":"TiCDC","count":11},{"name":"TiDB 4.0 新特性","count":11},{"name":"DM 源码阅读","count":10},{"name":"Contributor","count":9},{"name":"TiDB Binlog 源码阅读","count":9},{"name":"TiFlash 源码阅读","count":9},{"name":"TiDB Hackathon 2022","count":8},{"name":"技术出海","count":8}]}},
    "staticQueryHashes": ["1327623483","1820662718","3081853212","3430003955","3649515864","4265596160","63159454"]}