Design a user system

Design a User System

Scenario

  • Sign up, Log in, Modify profile, Reading profiles
    • demands? 90% read, 10% write
  • Assume: 100 million daily user (DAU)
  • QPS:
    • log in/sign up/modify profiles
      • 10% users SignUp/LogIn/ChangeProfile 1 time/day=> 100M * 0.1 / 86400 -> about 100QP
      • peek: 100 * 3 = 300
    • reading requests:
      • 100M * 100 / 86400 -> about 100k QPS
      • 100:
      • peek: 100k * 3 = 300k, almost 98% of the data can be cached.
  • why QPS important?
    • MySQL/PosgreSQL: about 1k QPS, but if you execute complex queries, can't reach to this number. It's just an estimate.
    • MongoDB/Cassandra: about 10k QPS
    • Redis/Memcached: about 100k~1m QPS. Memcached can not persist data, but Redis can persist data.
  • Cache always in memory?

    • No
    • file system can be cache
    • CPU has L1 ~ L3 cache
    • front end, server side, browser.
    • browsers have cache. when visit a pic, and reload the page. very fast.
  • How to choose data storage.

    • for logIn/SignUp/Modify Profiles => RMDBS, like MySQL can easily handle 300 QPS
    • for the 300K read request, and most of the read heavy system, must use cache. Most data stays same.
# use cache to optimize
class UserService:
    def getUser(self, userId):
        key = "userId::%s" %userId
        user = cache.get(key)
        if (user):
            return user
        user = database.get(userId)
        return user
    def setUser(self, user):
        key = "userId::%s" %userId
        # always delete user first
        # make sure single source of truth
        # better not modify cache.
        cache.delete(key)
        database.set(user)

Service

  • AuthService: authentication

    • how to keep logged in status? session
    • when user login:
      • create a session object
      • return session_key as cookie to browser. (universal unique hashed value), do not use userName, it is too easy to be guessed by others
      • browser store this value in cookie.
      • every time, send request to server with cookie
      • server check the session_key, if it is valid, the user is logged in
    • another way:
      • check it in front-end
    • logout:
      • delete the session table
    • session table:
      • session_key:string
      • userId:Foreign key to User table
      • expire_at:timestamp
    • where to store session table:
      • DB (not very good. every time need look up in the DB)
      • Cache
  • UserService: get user profile

  • FriendshipService: friend relationship

summary:

  • what if read heavy & write heavy
    • cluster + LB
    • use Cache-through database like Redis.

results for ""

    No results matching ""