Skip to content

Instantly share code, notes, and snippets.

@safecat
Created October 22, 2015 09:54
Show Gist options
  • Save safecat/2a56a807a0ff507d769e to your computer and use it in GitHub Desktop.
Save safecat/2a56a807a0ff507d769e to your computer and use it in GitHub Desktop.
Timeline Design

####Timeline Design Redis

# 用户发的Feed
user.$id.feeds = ZSET{
	$timestamp : $feed_id,
	$timestamp : $feed_id,
	...
}
# likes
user.$id.feed_likes = LIST[$user_id, $user_id, ...]
# comment
user.$id.comment = LIST[$comment_id, $comment_id, ...]

# 用户的 Timeline
user.$id.timeline = ZSET{
	$timestamp : $feed_id,
	$timestamp : $feed_id,
	...
}

# 我的好友
user.$id.friends = SET[$user_id, $user_id, ...]
# 我不给谁看
user.$id.block_you = SET[$user_id, $user_id, ...]
# 谁不看我
user.$id.block_me = SET[$user_id, $user_id, ...]

# Feed 只给谁看
feed.$id.only_to = SET[$user_id, $user_id, ...]
# Feed 不给谁看
feed.$id.not_to = SET[$user_id, $user_id, ...]

Memcache

# Feed 信息(包含图文、声音、位置)
feed.$id = json(Feed Object)
# Comment 信息
feed.comment.$id = json(Comment Object)
# User 信息
user.$id = json(User Object)

限制

  • 微博限制一个用户只能查看最近的400条feed

业务

  • 发送Feed。满足了不给谁看和只给谁看

     # 用户发feed,不给谁看
     ZADD user.self.timeline $feed_id
     
     # 取差集
     if 只给谁看
     	SADD feed.$feed_id.only_to $allow_f_ids
     	friends = SDIFF feed.this.only_to user.$self_id.friends
     					user.self.block_me
     else
     	SADD feed.this.not_to $deny_f_ids
     	friends = SDIFF user.self.friends user.$self_id.block_you 
     					user.self.block_me feed.this.not_to
     
     #推送到好友的timeline
     pipe(i in friends)
     	ZADD user.friends[i].timeline $feed_id
  • 不让他看我。

     # 先上锁
     SADD user.$self_id.block_you $friend_id
     
     # 在他的timeline里面去除我的feed
     SDIFFSTORE user.$friend_id.timeline
     				user.$friend_id.timeline user.$self_id.feed
  • 刷新timeline
    加入用户刚刚刷新过,所有的数据都有缓存,那么可以有如下的业务逻辑。

# 找到所有的feed_id
feed_ids = ZRANGE user.$user_id.timeline 0 20

# 找到feed所有的like_user_id (20 in 1)
pipe(i in feed_ids)
	like_user_ids = LRANGE feed.$feed_id1.like
							LRANGE feed.$feed_id2.like ...

# 找到feed所有的comment_id (20 in 1)
pipe(i in feed_ids)
	comment_ids = LRANGE feed.$feed_id1.like
							LRANGE feed.$feed_id2.like ...

# 找到所有的feed (20 in 1)
memcache->get(feed_id1, feed_id2, ...)
							
# 找到所有的comment (20x20 in 1)
memcache->get(comment_id1, comment_id2, ...)

# 找到所有的用户 (500 in 1)
memcache->get(user_id1, user_id2, ...)					
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment