获得徽章 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
展开
Go学堂于2023-12-05 10:35发布的图片
评论
今天踩到一个gorm的坑,gorm.Save函数在保存的时候,如果待保存的数据中只包含了表的部分字段,那么未包含的表字段将会自动的更新成对应类型的默认值。

例如有一个表包含了id,name,address,若更新的数据中只有id和name字段,那么使用save函数更新时,会把address字段更新成空值。 #每天一个知识点#
展开
2
#每天一个知识点#
开发者都应该懂的缓存系统
从前端到后端的各个环节都有数据缓存!上图说明了在典型架构中我们缓存数据的位置。

沿着架构流程有多个缓存层级。

🔹 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:用于记录数据库集群中的复制状态
展开
Go学堂于2023-11-21 22:24发布的图片
评论
公众号 「Go学堂」
下一页
个人成就
优秀创作者
文章被点赞 541
文章被阅读 125,328
掘力值 5,751
收藏集
0
关注标签
13
加入于