<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>database | Academic</title><link>https://loloxwg.top/tag/database/</link><atom:link href="https://loloxwg.top/tag/database/index.xml" rel="self" type="application/rss+xml"/><description>database</description><generator>Wowchemy (https://wowchemy.com)</generator><language>en-us</language><lastBuildDate>Sat, 18 Jun 2022 19:34:40 +0000</lastBuildDate><image><url>https://loloxwg.top/media/icon_hu0b7a4cb9992c9ac0e91bd28ffd38dd00_9727_512x512_fill_lanczos_center_3.png</url><title>database</title><link>https://loloxwg.top/tag/database/</link></image><item><title>A fault-tolerant KV server on top of Raft</title><link>https://loloxwg.top/posts/a_fault-tolerant_kv_server_on_top_of_raft/</link><pubDate>Sat, 18 Jun 2022 19:34:40 +0000</pubDate><guid>https://loloxwg.top/posts/a_fault-tolerant_kv_server_on_top_of_raft/</guid><description>&lt;p>分享一下前两天在 &lt;a href="https://asktug.com/t/topic/665859" target="_blank" rel="noopener">Talent Plan Community&lt;/a> 华东师范大学孙佳丽做的有关 TinyKV 的介绍&lt;/p>
&lt;p>这次分享主要从TinyKV的整体架构,组件介绍,调用流程,raft优化四个方面展开，并给出了一些有用的参考&lt;/p>
&lt;p>注：以下仅为图片，&lt;/p>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="A%20fault-tolerant%20KV%20server%20on%20top%20of%20Raft_01.png" alt="" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="A%20fault-tolerant%20KV%20server%20on%20top%20of%20Raft_02.png" alt="" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="A%20fault-tolerant%20KV%20server%20on%20top%20of%20Raft_03.png" alt="" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="A%20fault-tolerant%20KV%20server%20on%20top%20of%20Raft_04.png" alt="" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="A%20fault-tolerant%20KV%20server%20on%20top%20of%20Raft_05.png" alt="" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="A%20fault-tolerant%20KV%20server%20on%20top%20of%20Raft_06.png" alt="" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="A%20fault-tolerant%20KV%20server%20on%20top%20of%20Raft_07.png" alt="" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="A%20fault-tolerant%20KV%20server%20on%20top%20of%20Raft_08.png" alt="" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="A%20fault-tolerant%20KV%20server%20on%20top%20of%20Raft_09.png" alt="" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="A%20fault-tolerant%20KV%20server%20on%20top%20of%20Raft_10.png" alt="" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="A%20fault-tolerant%20KV%20server%20on%20top%20of%20Raft_11.png" alt="" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="A%20fault-tolerant%20KV%20server%20on%20top%20of%20Raft_12.png" alt="" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="A%20fault-tolerant%20KV%20server%20on%20top%20of%20Raft_13.png" alt="" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="A%20fault-tolerant%20KV%20server%20on%20top%20of%20Raft_14.png" alt="" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="A%20fault-tolerant%20KV%20server%20on%20top%20of%20Raft_15.png" alt="" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="A%20fault-tolerant%20KV%20server%20on%20top%20of%20Raft_16.png" alt="" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="A%20fault-tolerant%20KV%20server%20on%20top%20of%20Raft_17.png" alt="" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="A%20fault-tolerant%20KV%20server%20on%20top%20of%20Raft_18.png" alt="" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="A%20fault-tolerant%20KV%20server%20on%20top%20of%20Raft_19.png" alt="" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="A%20fault-tolerant%20KV%20server%20on%20top%20of%20Raft_20.png" alt="" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="A%20fault-tolerant%20KV%20server%20on%20top%20of%20Raft_21.png" alt="" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="A%20fault-tolerant%20KV%20server%20on%20top%20of%20Raft_22.png" alt="" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="A%20fault-tolerant%20KV%20server%20on%20top%20of%20Raft_23.png" alt="" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="A%20fault-tolerant%20KV%20server%20on%20top%20of%20Raft_24.png" alt="" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;h2 id="参考资料">参考资料&lt;/h2>
&lt;ol>
&lt;li>&lt;a href="https://z.itpub.net/article/detail/29B4D408D967AE015AF40C2C47F7E5AE" target="_blank" rel="noopener">Etcd 之 Lease read&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://qtozeng.top/2019/01/15/etcd-raft-ReadIndex-%E7%BA%BF%E6%80%A7%E4%B8%80%E8%87%B4%E6%80%A7%E8%AF%BB%E6%BA%90%E7%A0%81%E7%AE%80%E6%9E%90/" target="_blank" rel="noopener">etcd-raft ReadIndex 线性一致性读源码简析&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://pingcap.com/zh/blog/optimizing-raft-in-tikv" target="_blank" rel="noopener">TiKV 功能介绍 - Raft 的优化 | PingCAP&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://pingcap.com/zh/blog/lease-read" target="_blank" rel="noopener">TiKV 功能介绍 - Lease Read | PingCAP&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://pingcap.com/zh/blog/tikv-source-code-reading-19" target="_blank" rel="noopener">TiKV 源码解析系列文章（十九）read index 和 local read 情景分析 | PingCAP&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://learn.pingcap.com/learner/course/510001/file/570002;offeringId=720002" target="_blank" rel="noopener">如何在 Raft 之上构建Key-Value Server&lt;/a>&lt;/li>
&lt;/ol></description></item><item><title>ClickHouse为什么这么快</title><link>https://loloxwg.top/posts/clickhouse%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%99%E4%B9%88%E5%BF%AB/</link><pubDate>Mon, 02 May 2022 12:34:40 +0000</pubDate><guid>https://loloxwg.top/posts/clickhouse%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%99%E4%B9%88%E5%BF%AB/</guid><description>&lt;p>Slide: &lt;a href="https://presentations.clickhouse.com/bdtc_2019/" target="_blank" rel="noopener">https://presentations.clickhouse.com/bdtc_2019/&lt;/a>&lt;/p>
&lt;h2 id="bottom-up自底向上的设计原则">Bottom-Up自底向上的设计原则&lt;/h2>
&lt;p>这个设计的思想就是：当你在考虑一个组件时，必须要考虑到它在底层的执行性能如何。
具体来说可以考虑这么几个问题：&lt;/p>
&lt;ol>
&lt;li>work的内层循环是怎么执行的&lt;/li>
&lt;li>内存中的数据布局是什么样的&lt;/li>
&lt;li>数据流是从哪里来的，又流向了哪里？&lt;/li>
&lt;li>我要设计GROUP By&lt;/li>
&lt;li>我要用Hash Table，并且要放到内存里&lt;/li>
&lt;li>如果HashTable太大那么没法使用L3级缓存&lt;/li>
&lt;li>如果GROUP BY的key不是在本地分配的，那么L3缓存对于每一行来说都是miss的&lt;/li>
&lt;li>L3 miss会造成70-100ns的损失&lt;/li>
&lt;li>目前ClickHouse的查询量是175million rows/s&lt;/li>
&lt;li>如果L3 miss的话只有40million rows/s&lt;/li>
&lt;/ol>
&lt;h2 id="algorithm-first-abstractions-go-after-算法优先于抽象">Algorithm First, Abstractions Go After 算法优先于抽象&lt;/h2>
&lt;p>应当根据业务，首先考虑出算法，再去考虑具体用什么样的接口去实现这个算法
&lt;strong>内置库函数为什么垃圾以及优化方法&lt;/strong>
很简单，Every problem is a landscape。
内置的库函数都是通用的，很难考虑到具体的业务。
比较常见的有&lt;/p>
&lt;ol>
&lt;li>子串查找strstr&lt;/li>
&lt;li>Sort&lt;/li>
&lt;li>HashTable&lt;/li>
&lt;/ol>
&lt;h3 id="子串查找">子串查找&lt;/h3>
&lt;p>考虑这么一种情况，有一个模式串(needle)和10000个匹配串(haystack)，如果要调用strstr的话需要&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="err">Searcher&lt;/span> &lt;span class="err">searcher(needle);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">for&lt;/span> &lt;span class="err">(const&lt;/span> &lt;span class="err">auto&lt;/span> &lt;span class="err">&amp;amp;haystack:&lt;/span> &lt;span class="err">haystacks)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="err">searcher.search(haystack)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>时间复杂度O(n * len(m))
那怎么办呢？&lt;del>当然是拿出AC自动机&lt;/del>
实际上有几十种子串查找算法可以使用 &lt;a href="https://www-igm.univ-mlv.fr/~lecroq/string" target="_blank" rel="noopener">https://www-igm.univ-mlv.fr/~lecroq/string&lt;/a>
但是ClickHouse一个都没用，而是根据needle是否为constant采用了下面几种算法
算法的具体介绍在这里 &lt;a href="https://habr.com/en/company/yandex/blog/466183/" target="_blank" rel="noopener">https://habr.com/en/company/yandex/blog/466183/&lt;/a>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="image-20220621013728023" srcset="
/posts/clickhouse%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%99%E4%B9%88%E5%BF%AB/image-20220621013728023-5746658-5746660-5746661_hu1f3ec6513e50f057d0eb5cfe13c95990_160156_ee05aab82b8ea66c9d141ad11f42317c.webp 400w,
/posts/clickhouse%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%99%E4%B9%88%E5%BF%AB/image-20220621013728023-5746658-5746660-5746661_hu1f3ec6513e50f057d0eb5cfe13c95990_160156_e9b2f27058c82c8708e35c947ef99b4c.webp 760w,
/posts/clickhouse%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%99%E4%B9%88%E5%BF%AB/image-20220621013728023-5746658-5746660-5746661_hu1f3ec6513e50f057d0eb5cfe13c95990_160156_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://loloxwg.top/posts/clickhouse%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%99%E4%B9%88%E5%BF%AB/image-20220621013728023-5746658-5746660-5746661_hu1f3ec6513e50f057d0eb5cfe13c95990_160156_ee05aab82b8ea66c9d141ad11f42317c.webp"
width="760"
height="167"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;h3 id="sort排序">Sort排序&lt;/h3>
&lt;p>排序需要考虑的因素有&lt;/p>
&lt;ol>
&lt;li>array的类型，numbers/tuple/string/structure ？&lt;/li>
&lt;li>是否需要完全在内存中进行？&lt;/li>
&lt;li>是否需要多路归并？等等等等&lt;/li>
&lt;/ol>
&lt;p>ClickHouse使用了pdqsort和radix sort
但是实现一般般，需要重写&lt;/p>
&lt;h3 id="hashtable">HashTable&lt;/h3>
&lt;p>需要考虑的因素有&lt;/p>
&lt;ol>
&lt;li>hash函数的选择&lt;/li>
&lt;li>内存布局：开放地址or拉链法？&lt;/li>
&lt;li>value的大小&lt;/li>
&lt;li>是否需要支持value不能被移动？&lt;/li>
&lt;li>等等..&lt;/li>
&lt;/ol>
&lt;p>ClickHouse的实现方法是
针对不同的业务场景实现N多个Hash函数&lt;/p>
&lt;h2 id="积极采用最新的算法grab-the-best">积极采用最新的算法Grab the best！&lt;/h2>
&lt;p>积极采用业界最先进的算法
如果有性能提升就采用
否则drop it
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="image-20220621013827247" srcset="
/posts/clickhouse%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%99%E4%B9%88%E5%BF%AB/image-20220621013827247_huf12aecf3d1a411d52c68f1d2a21d5dff_99434_727f9f1097b524aa6b61632aec7c1106.webp 400w,
/posts/clickhouse%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%99%E4%B9%88%E5%BF%AB/image-20220621013827247_huf12aecf3d1a411d52c68f1d2a21d5dff_99434_9f3418f88592ccc9bcb0768096893c54.webp 760w,
/posts/clickhouse%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%99%E4%B9%88%E5%BF%AB/image-20220621013827247_huf12aecf3d1a411d52c68f1d2a21d5dff_99434_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://loloxwg.top/posts/clickhouse%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%99%E4%B9%88%E5%BF%AB/image-20220621013827247_huf12aecf3d1a411d52c68f1d2a21d5dff_99434_727f9f1097b524aa6b61632aec7c1106.webp"
width="760"
height="194"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;h2 id="specialization-for-the-task-具体的问题具体处理">Specialization For the Task 具体的问题具体处理&lt;/h2>
&lt;h3 id="like查询">LIKE查询&lt;/h3>
&lt;p>以LIKE查询为例
对于
WHERE str LIKE &amp;lsquo;%hello%world!%&amp;rsquo;
来说，常见的解决方案是直接用re2匹配
但是ClickHouse会在这之前扫描一遍字符串，确保&amp;rsquo;world!&amp;lsquo;存在
而对于
WHERE str LIKE &amp;lsquo;%hello%&amp;rsquo;
则会执行substring search
对于
WHERE str LIKE &amp;lsquo;hello%&amp;rsquo;
则会执行prefix search&lt;/p>
&lt;h3 id="group-by">GROUP By&lt;/h3>
&lt;p>ClickHouse的GroupBy针对不同的数据类型，有40余种不同的HashTable实现
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="image-20220621013952264" srcset="
/posts/clickhouse%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%99%E4%B9%88%E5%BF%AB/image-20220621013952264_huf546420f7c81e1d37bef2a2618289c75_645068_7464f7df6a1f7a41857c0a017862fac8.webp 400w,
/posts/clickhouse%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%99%E4%B9%88%E5%BF%AB/image-20220621013952264_huf546420f7c81e1d37bef2a2618289c75_645068_a44d5873b40ab0024deab18f0813e5b4.webp 760w,
/posts/clickhouse%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%99%E4%B9%88%E5%BF%AB/image-20220621013952264_huf546420f7c81e1d37bef2a2618289c75_645068_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://loloxwg.top/posts/clickhouse%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%99%E4%B9%88%E5%BF%AB/image-20220621013952264_huf546420f7c81e1d37bef2a2618289c75_645068_7464f7df6a1f7a41857c0a017862fac8.webp"
width="760"
height="360"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;h3 id="quantiletiming-求中位数">QuantileTiming 求中位数&lt;/h3>
&lt;p>对于小于64个数字的数组，在arena申请内存
对于小于5670个数字的数组，在heap申请内存
对于其他的使用custom buckets&lt;/p>
&lt;h2 id="data-structures-are-always-in-context-of-the-task-数据结构需要考虑任务的上下文">Data Structures are Always in Context of the Task 数据结构需要考虑任务的上下文&lt;/h2>
&lt;p>如何选择一个数据结构？
想清楚，它需要实现什么，需要哪些，以及不需要哪些
例如std::string&lt;/p>
&lt;ol>
&lt;li>需要自己手动管理内存&lt;/li>
&lt;li>需要允许修改字符&lt;/li>
&lt;li>需要自己维护size&lt;/li>
&lt;/ol>
&lt;p>再比如，如何实现GROUP By？&lt;/p>
&lt;ol>
&lt;li>对数据排序后依次取&lt;/li>
&lt;li>Hash一下查Hash表&lt;/li>
&lt;/ol>
&lt;p>到底是用1还是2呢？
其实还是要看场景，如果数组几乎是排好序的，那么1合适，否则2合适&lt;/p>
&lt;h2 id="algorithm-know-about-data-distribution算法实现时考虑数据分布">Algorithm Know About Data Distribution算法实现时考虑数据分布&lt;/h2>
&lt;p>一个超硬核的例子。
理论上可以快12倍。
其实通过这个例子也可以看出，真实的数据应该是1/2/3位最多，在12位数以下，9位和10位最多
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="image-20220621014118592" srcset="
/posts/clickhouse%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%99%E4%B9%88%E5%BF%AB/image-20220621014118592_hu73e5a007f3e0a5f917d413306cf0f807_556697_c09a534a78a13719eb33fbd9c93c1739.webp 400w,
/posts/clickhouse%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%99%E4%B9%88%E5%BF%AB/image-20220621014118592_hu73e5a007f3e0a5f917d413306cf0f807_556697_2300f6cb9d5f041dee54537865be9e56.webp 760w,
/posts/clickhouse%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%99%E4%B9%88%E5%BF%AB/image-20220621014118592_hu73e5a007f3e0a5f917d413306cf0f807_556697_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://loloxwg.top/posts/clickhouse%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%99%E4%B9%88%E5%BF%AB/image-20220621014118592_hu73e5a007f3e0a5f917d413306cf0f807_556697_c09a534a78a13719eb33fbd9c93c1739.webp"
width="739"
height="760"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;h2 id="multi-armed-bandit">Multi-Armed Bandit&lt;/h2>
&lt;p>Multi-Armed Bandit的来源是这样的：
这类似于赌场中的老虎机，它有几个杠杆，玩家可以拉动这些杠杆来获得一些随机数量的钱。玩家可以按任意顺序多次拉动操纵杆。每个杠杆都有一个固定的概率给出相应的金额，但玩家不知道它是如何工作的，只能从玩游戏的经验中学习。一旦他们弄清楚了，他们就可以最大化他们的奖金。 最大化奖励的一种方法是根据先前步骤的游戏统计数据评估每个步骤中每个杠杆的概率分布。然后，根据收到的分配，我们在心理上为每个杠杆“赢得”随机奖励。最后，我们拉动在我们的心理游戏中获得最佳结果的杠杆。这种方法称为汤普森抽样。
针对于CK，其应用是：对于不同的业务场景，需要选择不同的压缩算法，因此可以先对一小部分数据进行压缩，根据执行的效率并结合概率的因素，选出最终的压缩算法
具体实现看这里https://habr.com/en/company/yandex/blog/457612/&lt;/p>
&lt;h2 id="testing-on-real-data">Testing on Real Data&lt;/h2>
&lt;p>用真实数据进行测试&lt;/p>
&lt;h2 id="summary">Summary&lt;/h2>
&lt;ol>
&lt;li>在设计系统时需要考虑底层的实现细节&lt;/li>
&lt;li>基于硬件容量设计&lt;/li>
&lt;li>根据任务需要决定数据结构和抽象&lt;/li>
&lt;li>对于特殊的case需要给出特殊的解法&lt;/li>
&lt;li>尝试新的，好的算法&lt;/li>
&lt;li>基于数据选择算法&lt;/li>
&lt;li>通过真实数据集进行测试&lt;/li>
&lt;li>在CI中测试数据衰减(databend好像是每天结束后会推送一次性能报告）&lt;/li>
&lt;li>测量和观察一切事物&lt;/li>
&lt;li>不断的重构代码&lt;/li>
&lt;/ol></description></item><item><title>Cmu15445 实现单机数据库</title><link>https://loloxwg.top/project/cmu15445/</link><pubDate>Wed, 09 Feb 2022 22:28:09 +0000</pubDate><guid>https://loloxwg.top/project/cmu15445/</guid><description>&lt;h1 id="cmu15445-课程介绍">Cmu15445 课程介绍&lt;/h1>
&lt;h2 id="大纲">大纲&lt;/h2>
&lt;p>简单介绍下 &lt;a href="https://15445.courses.cs.cmu.edu/fall2020/" target="_blank" rel="noopener">cmu15445&lt;/a> 的&lt;a href="https://15445.courses.cs.cmu.edu/fall2020/syllabus.html" target="_blank" rel="noopener">教学大纲&lt;/a>，该课以 &lt;a href="https://www.db-book.com/db7/index.html" target="_blank" rel="noopener">Database System Concepts&lt;/a> 为辅助教材， 讲述了数据库管理系统（DBMS）设计和实现的方方面面，包括：&lt;/p>
&lt;ol>
&lt;li>数据模型（关系型，文档型，键值型）&lt;/li>
&lt;li>存储模型（n-ary，decomposition，可以理解为行式、列式）&lt;/li>
&lt;li>查询语言（sql，存储过程 stored procedures）&lt;/li>
&lt;li>存储结构（heaps，基于日志 log-structured）&lt;/li>
&lt;li>索引设计（排序树，哈希表）&lt;/li>
&lt;li>事务处理（ACID，并发控制）&lt;/li>
&lt;li>数据恢复（日志、快照）&lt;/li>
&lt;li>执行引擎（joins，排序，聚集，优化）&lt;/li>
&lt;li>并发架构（多核，分布式）&lt;/li>
&lt;/ol>
&lt;p>可以看出，内容十分翔实，课程使用一个开源的商业数据库作为案例进行讲解，以深入探讨数据库设计时，在上述各个方面进行取舍的过程。&lt;a href="https://15445.courses.cs.cmu.edu/fall2020/assignments.html" target="_blank" rel="noopener">代码实验&lt;/a>。&lt;/p>
&lt;h2 id="计划">计划&lt;/h2>
&lt;p>这次学习目标主要以实验为主，兼顾看点讲义和教科书。视频暂时就随缘了，不然战线会拉很长，导致最后都搞不完。一共有五个实验：&lt;/p>
&lt;ol>
&lt;li>环境准备：&lt;a href="https://15445.courses.cs.cmu.edu/fall2020/project0/" target="_blank" rel="noopener">C++ Primer&lt;/a>&lt;/li>
&lt;li>缓冲控制：&lt;a href="https://15445.courses.cs.cmu.edu/fall2020/project1/" target="_blank" rel="noopener">Buffer Pool Manager&lt;/a>&lt;/li>
&lt;li>B+ 树索引：&lt;a href="https://15445.courses.cs.cmu.edu/fall2020/project2/" target="_blank" rel="noopener">B+Tree Index&lt;/a>&lt;/li>
&lt;li>查询引擎：&lt;a href="https://15445.courses.cs.cmu.edu/fall2020/project3/" target="_blank" rel="noopener">Query Execution&lt;/a>&lt;/li>
&lt;li>并发控制：&lt;a href="https://15445.courses.cs.cmu.edu/fall2020/project4/" target="_blank" rel="noopener">Concurrency Control&lt;/a>&lt;/li>
&lt;/ol>
&lt;p>五个实验组成了一个用于教学的简单的关系型数据库 —— &lt;a href="https://github.com/cmu-db/bustub" target="_blank" rel="noopener">BusTub&lt;/a>。 实验方式基本都是实现一些规定的接口，跑通写好的测试用例。需要说明的是，代码中给的测试用例十分简单，基本只测试了一些主干路径，因此跑过了测试用例并不一定说明你代码写的没问题，这就要求在实现的过程中务必理解实验各个接口的关系、可以进行取舍实现的要点。为了达到此目的，当自己做完并跑过测试用例后，可以在网上找一些前人实现的材料，对比学习。&lt;/p>
&lt;p>初步打算，除了第一个环境准备外，每个实验做完之后写一篇总结，探讨一些实现中遇到的问题和有趣的地方。&lt;/p>
&lt;h2 id="资料">资料&lt;/h2>
&lt;p>课程本身相关的资料都可以去&lt;a href="https://15445.courses.cs.cmu.edu/fall2020/syllabus.html" target="_blank" rel="noopener">课程网站&lt;/a>上寻找，我计划做 fall2020 年的实验，但&lt;a href="https://www.youtube.com/playlist?list=PLSE8ODhjZXjbohkNBWQs_otTrBTrjyohi" target="_blank" rel="noopener">视频&lt;/a>似乎只有 2019 年的。&lt;/p>
&lt;p>在实现过程中如果遇到比较好的博客或者资料，我会逐渐补充到这里。&lt;/p></description></item></channel></rss>