我需要存储 4 种尺寸的 25M 张照片 = 总共 100M 个文件,每个文件的大小在 3Kb 到 200 kb 之间,开始时使用的存储空间约为 14-15 TB。
我们的目标是让 2-4 台服务器上的数据可用,并使用本地快速的 Web 服务器(nginx 或 lighthttpd)为它们提供服务,我们需要提供尽可能多的服务器请求/秒。
我的计划是使用英特尔的 2U 服务器机箱,12x2TB(WD RE4)搭配 Raid 6(或带冗余的 FS??)来存储数据,2x60GB SSD 来存储操作系统,这是个好办法吗?现在:我发现 Adaptec 5805ZQ 可以使用 SSD SLC 驱动器来缓存最常用的文件,有什么建议吗?
我需要选择什么读取缓存大小?
如果我计划拥有 2-4 个这样的服务器,那么实现冗余和负载平衡的最佳方法是什么?
就我们的目标而言,集群和分布式 FS 之间有何优缺点?
答案1
如果这是绿地开发,那么我绝对会使用云来实现这一点。100 M 文件是很大的数据;将其冗余存储卸载到 Amazon S3 将是一个重大改进。
鉴于我们讨论的是 100 M 文件,我相信我们可以肯定地说数据集的某些部分将是“热的”(频繁请求的),而大多数部分将是冷的。因此我们确实需要缓存。
关于如何在 Amazon Web Services 上实现此目的的概述:
- 第一层:使用 Amazon 管理的 Elastic Load Balancing 和 Amazon CloudWatch 监控几个使用 nginx 或 Apache 的小型 EC2 实例。这些服务器只是具有静态配置文件的哑负载均衡器,因此 Cloudwatch 可以为我们监控它们,并在其中一个实例崩溃时自动生成新实例。
- 从第一层开始:根据请求 URL(文件名)进行一致加速到缓存服务器层。您希望基于文件名进行哈希处理,以确保每个文件不会被缓存多次(降低缓存命中率),而是使用 N 个缓存服务器,每个服务器处理 1/N 的地址空间。
- 第二层:缓存服务器。您的缓存服务器是具有更多内存的 EC2 实例,以及 Squid 或 Varnish 或Apache 流量服务器已安装缓存。
- 从第二层开始:普通的 HTTP 到 Amazon S3 文件存储。
由于此设置是松散耦合的,水平扩展很容易(随着扩展问题的出现)。
速度有多快在很大程度上取决于热数据和冷数据之间的比率。如果您的工作负载主要是热数据,那么仅从 2 个小型负载均衡器 EC2 和 2 个高内存缓存 EC2 实例中看到每秒超过 10,000 个请求就不足为奇了。
答案2
除非你真的真的希望启动速度快 30 秒,否则操作系统本身的 SSD 就有点过头了。只需一对小型 SAS 驱动器就足够了。
对于缓存,缓存的实用性取决于工作集。即,对图像的请求是否预计均匀分布在所有图像中,或者您是否预计大多数请求将针对一小部分?在后一种情况下,缓存可能有用,在前一种情况下,则没那么有用。请注意,磁盘控制器上的缓存主要用于缓存写入(如果缓存是非易失性的),这对于 fsync() 密集型应用程序(如数据库)很有帮助。对于图像服务,我怀疑好处不会那么大。
集群和分布式 FS 的一个问题是设置起来更复杂,尤其是分布式 FS 不如“普通”单节点 FS 成熟。集群 FS 通常意味着共享存储,这意味着如果您想避免单点故障,则需要相对昂贵的 SAN。
另一种方法是设置一个集群,运行某种类似于 Amazon S3 的程序,提供可通过 HTTP 访问的分布式和复制的键值存储。例如OpenStack存储。
答案3
很大程度上取决于这些项目的使用频率。如果您预计其中一小部分会同时非常活跃,那么您可能需要考虑使用 Varnish 进行前端处理,并在 nginx/lighttpd 后端之间进行负载平衡。由于经常使用的图像会被缓存,因此磁盘速度就没那么重要了。
但是,如果图像没有被重复请求,并且缓存不会提供巨大的提升,那么一台或两台服务器上的 nginx/lighttpd 就可以做到这一点。您还需要考虑要提供的带宽量。800mb/sec 的数据集小子集很容易被操作系统缓存。800mb/sec 的数据集大子集可能会遇到 IO 瓶颈,因为您无法足够快地从磁盘获取数据以供使用,在这种情况下,您需要将系统拆分成足够的部分以获得 IO 带宽。
即使您正在运行 raid-6,它也仍然不能替代备份,因此,预算一台类似的机器来进行备份,或者可能充当故障转移存储服务器。
答案4
我会选择自定义集群而不是分布式 FS,因为它更容易理解和排除故障,同时还能正常工作。也就是说,您自己的集群的可靠性权衡是显而易见的,而弄清楚分布式 FS 如何应对死机服务器或故障交换机则是一项独立的任务。
解决您这种问题的一种可能方法是将整个照片档案分成几部分(比如说,2 个部分),并在 URL 中明确说明部分 ID(例如,使其成为子域或易于用正则表达式提取的 GET 参数)。然后,您将拥有 4 个存储照片的服务器(每个部分 2 个服务器)。使用第五个服务器作为反向代理,以分配和平衡负载。所有五台服务器都可以运行 lighttpd。也就是说,我提出了一个非常愚蠢但可行的解决方案(对于我工作的公司 - 总负载约为每秒 5000 个请求,文件大小为 3-10 KB,唯一文件总数为 8 TB,服务器来自 24 个后端,但是,它们运行自定义 HTTP 守护程序而不是 lighttpd)解决方案。
至于磁盘和 RAM:我们在每台服务器上使用由四个快速但便宜的 SATA 磁盘组成的软件 RAID-0(如果磁盘发生故障,所有数据都可以从另一台服务器上的副本中复制),再加上一个自定义解决方案,在一次读取错误后使整个服务器脱机。即使一个磁盘发生故障,RAID-5 和 RAID-6 的速度也非常差,请不要使用它们。在内容服务器上,大量的 RAM 是必不可少的(作为磁盘缓存),请寻找 24 GB 或更多。即便如此,也要准备好 30 分钟的预热时间。在反向代理上,如果您使用 lighttpd,请考虑到它会尽快将整个上游响应缓冲到 RAM 中,并且可能会花费大量时间将缓存的照片推送给拨号或 GPRS 上的某个人(在此期间,需要 RAM 中的缓冲区)。我们还使用了 24 GB 只是为了获得相同的配置,但我不确定这是否是过度的。反向代理上的基于内存的 HTTP 缓存不是必需的(即使有热门图像!),因为后端操作系统提供的磁盘缓存同样有效。
确保为档案的同一部分提供服务的所有后端都具有相同的数据:这很容易。发布照片时,只需将它们复制到所有服务器。然后对档案的旧部分使用 rsync 来纠正任何差异,从而将一份副本作为主副本。