答疑课堂 思考题答案(二)
你好,我是编辑小新。
今天是我们第二次答疑课。上一次加餐,我们公布了前面九节课的思考题参考答案。这次我们把后面课程的思考题答案,一并公布出来,同样地,一些优秀同学的答案也做了展示。
建议你自行思考之后,再对答案。每节课都附上了超链接,方便你跳转回顾。现在课程刚刚结课不久,也非常希望你分享一下自己的学习体会,花几分钟填一下后面的毕业问卷。
思考题答案
Q:请你思考一下:列存储数据库为什么能够提高OLAP查找性能?
A:原因有三点。第一,列存储的数据会有很多相近的数据在同一列,相对来说更好压缩;第二,列存储数据库提供了小索引,每隔一定条数就会产生一个小索引,这个索引可以加快查询和计算速度;第三,我们做汇总计算时,列数据库可以只读取参与计算的列数据,比读取全量的行数据库更有效率。
Q:既然我们通过ELK实现Trace那么简单,为什么会在当年那么难实现?
A:核心在于2014年的时候服务器资源并不丰富,没有PCIE的SSD。而且,那时还没有现在的大型分布式存储及索引开源,很难支撑每天1T的数据量,当时数据库超过100G都会很难维护。
Elasticsearch和Kafka刚出来的时候,还没有公认统一的Raft标准它们的实现是根据Paxos自行改进的。当时索引最好用的也只有Lucene以及Sphinx,连分词只有二元分词。
Q:如果让你实现一个Elasticsearch,你觉得需要先解决的核心功能是什么?
A:需要实现日志采集、分布式日志传输、分片存储、分片索引、分片查询、数据统计缓存、数据统计、分词。其中最核心的地方在于——如何解决大量数据的索引、查询问题。
Q:基于这节课讲到的算法和思路,SQL如何做聚合归类去重?
A:可以借鉴URL去参数思路去掉SQL参数。还可以通过AST对SQL进行去参数加工,比如阿里巴巴提供的druid,这是一个数据库连接池,感兴趣的话你可以点这里了解。
Q:ClickHouse是不能轻易修改删除数据的,那我们要如何做历史数据清理呢?
A:选可选的可以删除数据的引擎,但是性能不好,或使用mutations工具。
对于这个问题,还可以参考后面这两位同学的回答。首先是@Elvis Lee的回答。
1.设置TTL
2.表使用ReplaceMergetree
另外,@移横为固同学的思路也很优秀。有简单使用clickhouse,考虑到clickhouse的特性,对需要修改的数据是不放入clickhouse存储。在历史数据清理上,使用过两个方法:
1.clickhouse支持过期删除策略,可以根据表中的时间字段设置过期时间,让clickhouse帮忙自动删除过期数据。
2.clickhouse存储数据会对数据进行分区存储,建表时就可以设置好分区字段,类似平常所说的水平分表。在删除数据时可以查找到表的分区信息,按分区删除数据。
Q1:如何解决Kafka消费偶发的乱序以及小概率消费重复问题?
A1:使用uuid以及timestamp+实体id,在Redis内setnx。
Q2:epoll实现时会分单线程Reactor、单Reactor多线程、多线程Reactor几种方式,对于存储服务你觉得哪种更适合?
A2:由于具体实现很复杂,具体请参考epoll相关内容。我们可以通过epoll对网络accept进行操作,还能在后续解包时选择异步、阻塞IO模式处理以及是否使用多线程,这些都可以根据不同的业务场景灵活调整。
Q:使用了大数组来保存数据,用offset+length实现的数据缓存,有什么办法修改数据?
A:如果是定长的数据,很好修改,替换即可。如果是变长的数据建议不修改,而是后台定期做合并数据整理,但是同时会有一定性能损耗代价。
Q:如何让Go的协程访问一个LState保存的数据?
A:在lua内定义函数,通过Go调用其函数即可获取。
Q:既然CDN能够缓存我们的静态数据,那么它是如何识别到我们本地的静态数据有更新的呢?
A:我们先看看@brqi同学的思路。
可以通过MD5一下缓存文件,对比md5值就知道变化了,可以采用文件名称+文件md5值来判断,降低MD5值冲突风险。
这个思路没问题,通过这个方式可以识别文件是否修改。也建议继续深入想一想——什么时候CDN会知道我们更新资源了。
其实,CDN是通过Http Header的etag以及Expire来识别我们本地静态数据是否更新。在这里,问这个问题主要是因为这也涉及了一个客户端缓存技巧,它能帮助我们做一些客户端数据缓存更新。
Q:视频、WebSocket这一类长链接如何动态切换机房?
A:需要先断开链接,当机房出现故障时,可以分批主动关闭连接的客户端长链接,帮助他们快速切换。同时,注意我们客户端应该具备失败切换IP重试功能,或服务端发送指令告诉客户端切换。
Q:L1缓存使用BloomFilter来减少L1缓存查询,那么BloomFilter的hash列表如何更新到客户端呢?
A:通过Nacos、etcd动态配置推送,或者客户端定期拉取L1缓存中保存的BloomFilter列表。
Q:分布式存储通过文件块作为单位来保存管理小文件,当我们对文件内容进行更新时,如何刷新这个文件的内容呢?
A:大部分的分布式存储服务不支持随机读写,只支持覆盖和append操作。所以。我们的修改一般是全量地重新上传,然后修改文件索引到新的文件块,从而实现多个版本的切换。
Q1:建设日志中心,使用云厂商的服务贵还是自己建设的贵?
A1:一般来说如果我们的服务流量在10W QPS,存储不超过1PB,且业务服务器小于50台,这时云服务商比较合适;如果超过以上量级,则会牵扯到各种业务及硬件特殊优化的问题,这时选择自建日志中心会更节省成本。当然这个数值只是参考值,毕竟业务形态不一样情况不一样。
Q2:大数据挖掘服务如何计算成本?
A2:这个问题比较复杂,这里主要列出大致思路。你需要先推算每天任务的计算数据量,再以此推断存储容量,最终才能计算需要多少台,你可以参考如下指标进行计算:
- 测试你的CPU每秒能计算多少数据量。
- 大数据交换过程中需要放在内存中的数据量。
- 单台服务器的网络吞吐能力。
另外,搭配OLAP可能会帮我们节省一部分成本。
Q:为什么内网都在用网关或实现服务发现功能,而不用内网DNS服务来实现这一功能呢?
A:因为DNS有本地缓存,更新会延迟,并且只能发现一类服务无法达到接口级别。除此之外,常见服务发现能够通过label做服务筛选,提供一个服务多个版本同时服务的功能。
Q:如何保证上线前的单元测试里,测试生产的数据不会污染线上环境?
A:使用虚拟机镜像在独立一个小环境中运行中,独立跑一个数据支撑环境。
@LecKey同学的方法也不错,这里一并放出供参考。
在代码中对“单元测试里”做个标识,是单元测试的数据进入单独 “影子库”中。
以上就是第十课到第二十四课的思考题答案,如果你有更多问题,欢迎继续在对应课程的留言区里分享,我们共同讨论。