Designing a Fast, Reliable, Cost‑Effective Like System for High‑Traffic Apps
This article breaks down the essential requirements and architecture of a high‑performance like system, covering fast response, data consistency, scalability under traffic spikes, and cost‑efficient resource use, while detailing the technical stack, caching strategies, async persistence, and practical optimizations.
Why a Like Button Matters
Users expect an instant visual change; if the button does not change color within 3 seconds, 90% abandon, and duplicate counts cause distrust.
Requirement Breakdown
Fast – sub‑second response : End‑to‑end latency should stay under 200 ms, otherwise users notice lag.
Accurate – no loss, no duplicate : Use eventual consistency; cache must reflect the latest state and prevent double counting.
Stable – handle traffic spikes : A popular post can generate 3 000 likes/s (up to 10 000 req/s).
Cost‑effective – resource optimization : Classify data into hot, warm, and cold tiers.
Data Tiering
Hot data (real‑time like counts) lives in Redis; warm data (30‑day history) in MySQL tables; cold data (over 3 months) archived to low‑cost storage.
Technical Stack
Redis – cache champion : supports rich data structures, atomic ops, Lua scripts, and persistence (RDB+AOF).
Message Queue – Kafka or RabbitMQ : decouple like count update from persistence; choose Kafka for massive throughput, RabbitMQ for ease of use.
MySQL – durable storage : stores full like records for audit, user‑like lists, and analytics.
Frontend Layer
Immediately change button color and show "+1" animation, then send an asynchronous request. On network failure, cache the request in localStorage and retry later with a user hint.
Service Layer
Validate parameters, check like status in Redis, and perform atomic increment/decrement. Ensure idempotency with a unique requestId and a distributed lock.
Cache Layer
Two core data sets:
User‑to‑content mapping – Set for existence check or Hash for timestamped likes.
Content like count – String key like:count:{contentId} with INCR/DECR.
// Add like
Redis.sAdd("like:status:123", "456");
// Check like
Redis.sIsMember("like:status:123", "456");
// Hash version with timestamp
Redis.hSet("like:status:123", "456", "1629260800000");
Redis.hExists("like:status:123", "456");
Redis.hGetAll("like:status:123");Persistence Layer
After updating Redis, publish a message like "user 2001 liked content 1001" to Kafka, then a consumer writes to MySQL. Logical delete uses is_canceled flag.
CREATE TABLE `like_records` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`user_id` bigint NOT NULL COMMENT '用户ID',
`content_id` bigint NOT NULL COMMENT '内容ID(如动态ID、评论ID)',
`content_type` varchar(20) NOT NULL COMMENT '内容类型(区分动态、评论等)',
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '点赞时间',
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间(取消点赞时更新)',
`is_canceled` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否取消点赞(0-正常,1-取消)',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_user_content` (`user_id`,`content_id`,`content_type`) COMMENT '防止重复点赞',
KEY `idx_content` (`content_id`,`content_type`) COMMENT '按内容查点赞记录'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户点赞记录表';Full Architecture
Four logical layers: Frontend → Service → Cache (Redis) → Persistence (Kafka → MySQL). Each layer handles specific responsibilities such as UI feedback, business logic, fast data access, and durable storage.
Key Optimizations
Lua scripts for atomicity : combine status check and count update into a single Redis operation.
Cache expiration strategies : hot keys expire after 24 h, warm after 1 h; use proactive refresh, periodic sync, and pre‑warming.
Bloom filter & cache‑empty‑key to prevent cache‑penetration.
Hierarchical cache : local in‑process cache (Caffeine, sync.Map) + Redis reduces load.
Read‑write splitting & sharding : master for writes, slaves for reads; shard like_records by content_id % 16 to keep tables small.
Rate limiting & circuit breaking : token‑bucket in Redis, fallback responses when downstream services fail.
Conclusion
Prioritize user needs—speed, accuracy, stability, and cost—by choosing the simplest effective technologies: Redis for fast atomic ops, Kafka for async durability, MySQL for reliable storage, and layered caching and protection mechanisms to sustain massive traffic.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
IT Services Circle
Delivering cutting-edge internet insights and practical learning resources. We're a passionate and principled IT media platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
