Image Processing at Zillow: Out with the Old and In with the AWS
Bài tóm tắt Zillow 2015 2. Tăng trưởng Độ khó: Trung bình
Zillow · 2015 · 2. Tăng trưởng · Độ khó: Trung bình — bài gốc
Bối cảnh
- Zillow xử lý hơn 3 triệu ảnh mới mỗi ngày (2015): ảnh listing, ảnh hồ sơ, ảnh Zillow Digs; một phần upload tay, phần lớn đến theo feed hàng loạt từ hàng trăm nguồn, dồn cục trong ngày.
- Hệ cũ trong data center riêng: tải ảnh từ một hàng đợi duy nhất, lưu trên NAS dạng pyramidal TIFF (nhiều tầng JPEG nhỏ dần), scale theo yêu cầu khi có request rồi dựa vào CDN + Squid để cache.
- Vấn đề: một nguồn chậm ở đầu hàng làm kẹt mọi nguồn khác (head-of-line blocking), không tận dụng được nguồn cho tải nhanh mà lại dễ dội quá tải nguồn chậm; nếu cache bị xoá dù một phần, tải dồn về tầng scale động và NAS quá tải hàng giờ; DR kém; công cụ xử lý ảnh khó mở rộng.
Thay đổi chính
- Download Server (vẫn trong data center) quản lý yêu cầu tải từ feed và giữ DB ảnh đồng bộ với kết quả trên cloud.
- Một REST API trên Elastic Beanstalk nhận yêu cầu và đẩy vào một hàng đợi SQS cho mỗi feed.
- Throttled Downloader điều chỉnh tốc độ và độ song song theo từng nguồn; ảnh gốc ghi lên S3, lỗi vào hàng đợi lỗi.
- Image Processor (worker Beanstalk, Python PIL): làm sạch ảnh (bỏ viền màu đơn), render trước một bộ kích thước chuẩn lên S3; báo thành công/thất bại qua SQS.
- Phục vụ qua S3 + CloudFront, tới 15.000 ảnh/giây không gặp vấn đề hiệu năng (theo Zillow).
- Bài học vận hành: bản đầu thiếu metric nên không biết tầng nào gây trễ; phải thêm CloudWatch sau khi đã chạy. Autoscale theo CPU bị lừa bởi một instance hỏng (CPU luôn bằng 0, không nhận việc) nên thêm alert theo độ dài hàng đợi.
- Đánh đổi đã biết: render trước mọi kích thước nên khi thiết kế cần kích thước mới thì phải xử lý lại hàng trăm triệu ảnh; họ cân nhắc quay về scale lúc request đầu tiên (Lambda/GPU).
Vì sao
- Tách hàng đợi theo nguồn để một nguồn chậm không chặn nguồn khác, và giới hạn tốc độ theo nguồn để không dội quá tải nơi cấp dữ liệu (Event-driven, message queue và Kafka, Load shedding, rate limit và backpressure).
- Scale lúc đọc dựa hoàn toàn vào cache: mất cache là mất hệ; render trước đổi rủi ro đó lấy chi phí lưu trữ và chi phí xử lý lại (Cache và invalidation).
Bài học cho SWE
- Một hàng đợi chung cho nhiều nguồn có tốc độ khác nhau là công thức của head-of-line blocking.
- Tầng tính toán phía sau cache phải chịu được lúc cache lạnh, hoặc phải bỏ hẳn việc tính lúc đọc.
- Autoscale và alert nên dựa vào tín hiệu công việc (độ dài hàng đợi, độ trễ end-to-end), không chỉ CPU.
Liên quan
#Image pipeline#NAS#pyramidal TIFF#Squid#S3#CloudFront#SQS per-feed queue#head-of-line blocking#throttled downloader#Elastic Beanstalk worker#PIL#pre-render sizes#CloudWatch
Được nhắc tới trong
Chủ đề (3)
Công ty (1)
Bài tóm tắt (2)