Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Architectural Redesign of a Feed Stream System

Tech May 9 4

A legacy feed stream feature within an educational mobile application suffered from severe performance degradation and code decay. The system managed dynamic content (images, videos, audio) to student-teacher interactions within class groups. The existing monolithic service, built on MySQL with over 20 million records across core tables, relied heavily on stored procedures, leading to frequent query timeouts exceeding 5 seconds.

Refactoring Objectives

  • Decompose the monolith into maintainable modules.
  • Support flexible addition of new feed types.
  • Optimize the response time for aggregated feed pages.

Architectural Changes

Service Decomposition

The original service was split into:

  • API Service: Exposes RESTful endpoints for client applications.
  • Task Service: Handles asynchronous tasks like notifications.

Database Strategy

Sharding Design

Given the write volume of approximately 20,000 entries per day, table partitioning was chosen over full sharding.

Primary Key Generation: A variant of the Snowflake algorithm was implemented.

  • 41-bit timestamp (millisecond precision)
  • 10-bit worker ID derived from crc32(sharding_key) % 1024
  • 12-bit sequence number, managed via Redis INCRBY with a configurable step.
  • Local caching was added to reduce Redis calls.
// Pseudocode for ID generation
long shardKeyHash = crc32(shardingKeyValue);
int workerNodeId = Math.abs(shardKeyHash % 1024);
String redisCounterKey = "id_gen:" + currentMillis;
long sequence = redisClient.increment(redisCounterKey, batchSize);
long uniqueId = combine(currentMillis, workerNodeId, sequence);

Routing Logic: Queries using the sharding key (e.g., user ID) are routed directly. For non-sharding key queries (e.g., by primary key), the worker ID embedded in the Snowflake ID is used to determine the partition.

Library Selection: sharding-jdbc was adopted for its lightweight client-side approach.

// Simplified sharding-jdbc setup
Map<String, DataSource> dataSourceMap = createDataSources();
ShardingRuleConfiguration ruleConfig = new ShardingRuleConfiguration();
ruleConfig.getTableRuleConfigs().add(createTableRule("feed_table", "feed_table_${0..3}"));
DataSource shardedDataSource = new ShardingDataSource(dataSourceMap, ruleConfig, props);

Query Optimization

Caching Strategy for Lists: Two patterns were considered.

  1. Cache entire pages: Simple but inefficient for frequently updated content.
  2. Cache individual items: Fetch IDs first, then retrieve items from cache, falling back to the database for misses. This was selected to its efficiency.

Feed Aggregation: Data for a feed (content, likes, comments) is cached in Redis.

  • Content: Stored as a Hash.
  • Likes: Stored as a ZSET (sorted by timestamp) of user IDs.
  • Comments: Stored as a ZSET of comment IDs, with full comment data in Strings.
  • Collections: Stored as Strings mapping user IDs to feed IDs.

A Redis pipeline is used to atomically update related data structures.

// Pseudocode for Redis pipeline
try (RedisPipeline pipe = redisClient.pipelined()) {
    pipe.zadd("likes:" + feedId, timestamp, userId);
    pipe.hmset("feed:" + feedId, contentMap);
    pipe.sync();
}

Asynchronous Processing

A lightweight wrapper around RocketMQ was developed to standardize message production and consumption. Features include:

  • Batch and single-message consumpiton modes.
  • Ordered message sending.
  • Basic retry logic for broker throttling scenarios.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.