
获得徽章 7
- #每天一个知识点# 下图展示了架构中高可用、高性能和高扩展常用的解决方案。
1. 高可用性
这意味着我们需要确保系统高水平的正常运行时间。我们经常将设计目标描述为“3个9”或“4个9”。“4个9”,即99.99%的正常运行时间,意味着服务每天只能停机8.64秒。
为了实现高可用性,我们需要在系统中增加冗余节点。有以下几种方法可以做到这一点:
● hot-hot结构:两个实例接收相同的输入并将输出发送到下游服务。如果其中一个实例停机,另一个实例可以立即接管。由于双方都向下游发送输出,下游系统需要进行重复数据删除。
● hot-warm结构:两个实例接收相同的输入,只有hot实例将输出发送到下游服务。如果hot实例发生故障,warm实例将接管并开始向下游服务发送输出。
● single-leader Cluster:一个leader实例从上游系统接收数据并复制到其他副本。
● Leaderless cluster:在这种类型的集群中没有领导者。任何写入操作都会被复制到其他实例。只要写入实例的数量加上读取实例的数量大于实例的总数,我们就会得到有效数据。
2. 高性能
这意味着服务需要在一段时间内处理大量请求。常用的指标是QPS(每秒查询数)或TPS(每秒事务数)。
为了实现高性能,我们经常在架构中添加缓存,这样请求就可以在不命中数据库或磁盘等较慢的I/O设备的情况下返回。我们还可以增加计算密集型任务的线程数量。然而,添加太多线程可能会降低性能。最后,我们需要识别系统中的瓶颈并提高其性能。使用异步处理通常可以有效地隔离繁重的组件。
3. 高可扩展性
这意味着系统可以快速轻松地扩展以容纳更多容量(横向可扩展性)或更多功能(纵向可扩展性)。通常,我们会观察响应时间以决定是否需要扩展系统。
为了实现高可扩展性,重要的是将服务的职责分离。为此,微服务被广泛采用。我们还利用服务注册表和负载均衡器将请求路由到适当的实例。goxuetang.github.io
展开赞过评论3 - #每天一个知识点#
开发者都应该懂的缓存系统
从前端到后端的各个环节都有数据缓存!上图说明了在典型架构中我们缓存数据的位置。
沿着架构流程有多个缓存层级。
🔹 1. 客户端:HTTP响应的内容可在浏览器中进行缓存。我们首次通过HTTP请求数据,并在HTTP头部返回一个过期策略;我们再次请求数据,客户端会首先从浏览器缓存中获取数据。
🔹 2. CDN:CDN缓存静态Web资源,客户端可以从附近的CDN节点获取数据。
🔹 3. 负载均衡器:负载均衡器也可以缓存资源。
🔹 4. 消息中间件:消息中间件首先将消息存储在磁盘上,然后消费者根据自己的策略从消息中间件中获取数据。根据保留策略,数据在Kafka集群中缓存一段时间。
🔹 5. 服务层:服务层中有多个缓存层。如果数据不在CPU中缓存,服务将尝试从内存中获取数据。有时,服务具有二级缓存来存储磁盘上的数据。
🔹 6. 分布式缓存:像Redis这样的分布式缓存可以将数据存储在内存中。它提供了比数据库更好的读写性能。
🔹 7. 全文搜索:我们有时需要使用全文搜索,如Elastic Search,进行文档搜索或日志搜索。同时,在搜索引擎中建立数据的副本索引。
🔹 8. 数据库:即使在数据库中,我们也有不同级别的缓存:
- WAL(预写日志):在构建B树索引之前,数据首先写入WAL
- Bufferpool:分配给查询结果缓存的内存区域
- 物化视图:预先计算查询结果并将其存储在数据库表中以获得更好的查询性能
- 事务日志:记录所有事务和数据库更新
- Replication log:用于记录数据库集群中的复制状态展开赞过评论1 - #每天一个知识点# 在编程语言中,字符串能通过crc32函数变成一个整型值,你知道这是为什么吗? 原因就是计算机的对任何信息都是用二进制表示的。而字符串的本质也是通过数字编码的。比如ASCII码,所以字符串本质上是一个整型值。评论点赞
- #每日快讯# 今天学习了gin中recovery的应用。gin使用recover捕获了子协程中的panic,确保主协程能够正常提供服务不被down机。公众号:Go学堂评论点赞
- #每日快讯# 今天发现了一个检测MIME类型的go开源包,竟然支持172种类型的检测。真是很受欢迎的一个包。关注Go学堂评论点赞
- #挑战每日一条沸点# 今天把gin框架中的分块输出相关的源代码看了一遍。分块传输是基于http的Transfer-Encoding:chunked协议。同时在gin中将内容通过Flush函数实时的从缓冲区强制刷新到客户端。
这里有个点,其实在gin的正常输出过程中,如果内容的大小超过了缓冲区的大小,也是会自动的采用分块输出的。展开赞过评论2 - 今天通过分析gin、iris和echo框架中的中间件实现,深入理解了中间件的运行模式和运行机制。解答了为什么在中间件中会有一条ctx.Next()代码的疑问。详情请查看:
xie.infoq.cn #码上掘金#
评论点赞 - 在Go1.18发布之前,没有泛型,那如果像解决函数针对不同类型进行复用问题,一般会有三种方案:通过接口参数并使用类型断言,或者使用反射。还有一种就是使用接口并通过具体类型进行实现接口方法。详情可参看:
mp.weixin.qq.com
赞过评论1