📜  系统扩展–优化权衡

📅  最后修改于: 2021-08-27 05:08:19             🧑  作者: Mango

Network Load Balancer(NLB)可以处理流量高峰,每秒处理数百万个请求,但是它不支持日志记录,因此请使用cloudwatch将所有日志保留在集中位置。在水平缩放之前需要考虑的事情。

  • 确保线程安全代码–用于水平扩展
  • 连接池,实例化时无直接连接
  • 资料管理

各种水平缩放选项:

  • Heroku –配置测功机的数量,增加单个测功机的功能。
  • HirePower –提供细粒度的控制,功能和灵活性。
  • 蔚蓝
  • 谷歌云
  • AWS
  • 还有更多的供应商

Web服务器并发设置:

  • Puma(对于Ruby / Rack)-通过web_concurrency标志的工人数,线程数。
  • NginX –具有高性能,稳定性,丰富的功能集,简单的配置以及较低的资源消耗。
  • Apache –用于Java Web应用程序

垂直缩放比例
放大系统称为垂直缩放。
优点–

  • 增加每个服务器的功能以获得所需的性能。

缺点–

  • 我们可以在一个实例上垂直扩展的数量的昂贵,实际的限制。
  • 扩展配置取决于平衡的成本,性能,资源使用率到可接受的水平。

使用缓存进行事务查询:
在缓存之前,我们需要得到以下问题的答案:是否可以提供最终的一致性或需要高度的数据一致性。为了最终的一致性– NoSQL DB。为了实现高度一致性/关键交易– RDBMS –付款交易示例。

缓存-Redis / Memcached:
Redis –
自动副本,快照。

Memcached –
多线程体系结构。
缓存类型:

  • 全局缓存–
    简单,有效仅在一定程度上有效。
  • 分布式缓存–
    API网关,Cloudfront – Lambda @ edge。

如何选择正确的缓存:

  • 系统是否写得很重并且读的次数更少-(基于时间的日志)。
  • 数据是否被写入一次并可以读取多次–(用户个人资料)。
  • 返回的数据是否始终是唯一的-(搜索引擎)。

暂存:

  • 通用,最适合读取繁重的工作负载。 (Memecached,Redis)。
  • 系统可以抵抗缓存故障。
  • 缓存中的数据模型可以不同于数据库中的数据模型。(针对–请求ID存储的多个查询响应的结果)。
  • 常见的写入策略是–直接写入数据库。 TTL用于提供过时的数据,直到TTL过期为止。如果需要数据更新–我们可以使缓存条目无效或使用直写式缓存方法。
  • 延迟加载数据

读取缓存:

  • 坐在与DB一致。
  • 如果发生高速缓存未命中,则高速缓存由数据库命中填充。
  • 延迟加载数据。
  • 最适合阅读繁重的工作量-(新闻报导)

缺点–
第一次总是缓存未命中。通过手动查询来预热/预热缓存。数据可能会变得不一致,写策略将是解决方案。
区别b / w缓存和读取缓存:
暂存-

  • 应用程序负责从数据库获取数据并填充缓存。
  • 数据模型可以不同。

    读取缓存–

  • 库或独立缓存提供程序都支持逻辑。
  • 数据模型将与数据库相同。

通过缓存写入–缓存写入策略:
写周围–
当第一个读取请求到来时,数据首先被写入DB,然后数据被写入高速缓存。

  • 它可以与通读和缓存一起使用。
  • 当数据只写入一次而读取的频率较低或从不读取时,性能良好。 (实时日志/聊天室消息)

写信–
首先将数据写入高速缓存,然后写入数据库。可以与通读结合使用。

  • 额外的写入延迟。
  • 保证一致性–无需使用任何缓存失效技术(DAX – Dynamo DB加速器)。
  • DAX可用作写缓存。应用程序可以写入Dynamodb并通过DAX读取它。可能的问题–负缓存条目,当DAX在无法消除的dynamodb表中找不到请求的项目时,DAX向用户返回空结果,而不是错误。

写回–
将数据写入缓存,缓存立即确认,经过一段时间的延迟后,它将数据写回到数据库。

  • 也称为后写。
  • 提高性能,有利于写繁重的工作负载。
  • 与通读结合使用时,可以很好地用于混合工作负载,在缓存中始终可以使用最新更新和评估的数据。
  • 对数据库故障具有弹性,可以容忍某些数据库停机时间。
  • 如果支持批处理或合并,则可以减少对数据库的总体写入,减少负载并降低数据库的成本,该数据库按请求数(DynamoDB)收费。
  • DAX是直写式的(因此对于繁重的应用程序,Dynamo db的成本不会降低)

笔记 –
如果我们在两个高速缓存中都使用Redis并写回以更好地吸收峰值负载期间的峰值,则在高速缓存发生故障的情况下,数据可能会永久丢失。
缓存逐出策略:

  • LRU –最近最少使用。也广泛用于搜索引擎中的所有位置。
  • 随机替换,FIFO –不经常使用。

N + 1个查询:
需要其他查询以获取完整的数据图片的查询。根本原因-体系结构问题或对数据检索注意事项的关注。解决方案–渴望加载相关记录,并在初始查询中获取记录。
低效的代码

  • 避免做占用大量资源的事情。
  • 迁移到更快的库。
  • 流式传输–使用流式传输上传excel或其他数据密集型加载任务,以最大程度地减少内存和CPU占用空间。
  • 将集合遍历移动到数据库,例如
    • 计算RDBMS中的记录总数,而不用代码来计算。使用单个聚合数据库查询。
    • 当只访问少数字段时,避免急于加载整个文档。

背景:
识别并分离可以延迟几秒钟或可以由另一个系统处理的任务。使用队列,根据类型分离作业-事务,用户触发的批量作业,单独队列中的关键作业-SQS。

使用只读副本执行这些非关键任务,例如–

  • 发送邮件
  • 产生报告
  • 上传配置/文件

资产修改:
加载之前,请确保所有资产均已压缩或优化。这样可以显着减少加载时间。使用部署脚本将压缩和压缩的前端资产– Webpack推送到S3。 S3将通过设置内容编码和内容类型来gzip。最大限度地自动化部署–使用AWS,Terraform的Cloudformation。

内存泄漏:
避免内存泄漏,它们可能会碰到交换内存(在实内存和虚拟内存之间交换数据(虚拟内存地址,在现代CPU中始终启用)是“交换”的。磁盘上的交换是交换空间)。避免重新启动服务器创可贴解决方案,尝试找出实际原因。

主机代管:
确保所有必需的微服务都位于一个区域中,以降低延迟并加快所有查询和操作的速度。

参考 :
维基百科
Redis vs Memcached
有关更多的系统设计概念,请参考–

https://lethain.com/introduction-to-architecting-systems-for-scale/