[System Design] 系统设计 (2) -- 数据库设计

linspiration

Database

Intermediary:

Memory -- In-memory DB(H2)
SSD (Flash)
Disk

Param:

IOPS
Latency
Throughput
Capacity -- persistence

Utilization: Search, Retrieval,

WHY NoSQL: Large Data → Large Box/Server → More small boxes

Distributed DB: sharding (DB) → Read: Replication/Caching → Write: LSM Tree

Solved: Scalability
Not Solved:

Query Language
Secondary Index: Primary Index is global, and Secondary Index in local(need to be created);
ACID transaction
Trust and Confidence

Database Categories:

Relational DB

NoSQL -- Twitter 2009 accidentally created a tag #nosql for event

Key-value style approach: Redis, Dynamo

Impl: persistent HashMap
Aggregate: value

Document style approach: MongoDB, CouchDB

JSON format Document → Document ID → Transparent
Aggregate: document

Column-family: Google Bigtable, HBase, Cassandra

Row-key → column family
Column family = key + value
Aggregate: column family

Graph style approach: Neo4j //different from a,b,c

Aggregate-Oriented DB

You can easily pull individual column/document/value back and forth about the case
Store the whole thing -- Atomicity
You can distribute the data by placing different aggregates on different nodes
Design Trade-off

CAP Theorem, which comes from ACID(Relational DB)

Consistency: Single Threading + Async
Availability: Every request must be processed
Partition
What we want: shortest latency and highest consistency

Choice

Only one search type: AODB (same aggregate)
Solution: Map-reduce
More searches: RDB

http://www.cnblogs.com/fxjwin...

-- IOPS Latency Throughput Capacity
Memory 10M 100ns 10GB/s 100GB
Flash 100K 10us 1GB/s 1TB
Hard Drive 100 10ms 100MB/s 1TB

Flash - lifetime IO limitation
Hard Drive - Mechanical seeking

延时: Latency = 1 second / IOPS
频率: IOPS

IOPS和Throughput并没有直接的关系,一般而言,Throughput不会限制IOPS。
IOPS是操作次数的频率,Throughput是吞吐量。

ACID

ACID,是指数据库管理系统(DBMS)在寫入/更新資料的過程中,為保證事务(transaction)是正確可靠的,所必須具備的四个特性:原子性(atomicity,或稱不可分割性)、一致性(consistency)、隔离性(isolation,又称独立性)、持久性(durability)。

四大特性

原子性:一個事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
隔离性:数据库允许多个并发事务同时对齐数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

设计用户系统 - 需求

S 支持哪些操作:注册,登录,查看信息
N

读写频率:

  • DAU = 1M, 每秒平均登录数 = 1M * 2 queries per day / 86400seconds = 25 QPS

  • Peak = 25 * 2 = 50 QPS
    数据量:

  • 1M * 10KB = 10GB

A 独立小系统:Web-DB 2-tier setup
K 存哪些数据:密码,基本信息;单机SQL

数据模型

Data Model - Basic Objects

Tweet Table
post_id content user_id

Relations & Foreign Key

谁赞了我的贴?
Add user list column in post table?(幼稚的做法)
Implementation:

Select users.user_id, users.name
From likes
Join users
On likes.user_id = users.user_id
Where likes.photo_id = 9

我赞了哪些贴?在user table也加post list column?
Scalability: 1M用户赞了一个贴之后,每个新赞都得把整个list读出再写回去。

索引 Index

实现快速查找。例如,用users.user_id或者users.email查找用户。
常见解法:

  • B+ Tree

    • Block based & Sequential Read -- 适合硬盘 -- Disk的sequential读写很快

    • 例如1M个nodes,用二叉树存,需要21层;如果用1024叉树,需要3层;

    • check memory的话,搜索一个node,二叉树要搜索21 1 = 21次,1024叉树需要3 1023 = 3K次

    • check Hard Drive的话,二叉树需要21次,1024叉树层数少,所以只需要3次(延时远大于check memory);其次,B+ Tree内容都在叶子结点,一大块一大块连续存储,硬盘读取更快。(使用sequential read,利于在同一个level的顺序查找)

  • Hash: 更费空间一点

Transaction 交易

Scenario 场景: A付款给B,中途死机,无法完成transaction
Solution 解法:
Begin Transaction;
change userA.money;
change userB.money;
Commit Transaction;
Detail 实现细节: Log based Rollback

Write Ahead Log:

Begin Transaction;
//LOG: change userA.money from 10 to 0
change userA.money;
//LOG: change userB.money from 5 to 15
change userB.money;
/LOG: Success
Commit Transaction;

if you cannot find the log, roll back.
Trick: Save Logs on SSD(faster).

Will transaction and logs have race condition?
待续。

Evolution

More data

例如,100M用户,100TB数据。

  • 拆数据库

    • 根据应用把不同类型的数据放在不同的Database机器上

  • Tradeoffs

    • Relations不再存在

    • Transaction无法保证

  • 瓶颈:一张表都放不下了、或者Latency要求很高(需要存在Memory中)

    • Database sharding 拆表 (sharding key = primary key)

      • Transaction怎么办

      • Range Query或non-sharding key query需要查询多台机器

        • Latency ^

        • Reliability v

  • 数据继续增大,怎么办

    • 方案一:基于重建数据库的data migration(Function: % N)

      • 开N+1台新机器

      • Double Write(既写入老机器,也写入新机器)

      • 写一个小脚本

        • 从之前的机器读出所有数据

        • 依次写入新机器

        • Verification 看一致性

      • kill老机器

    • 方案二:Consistent Hashing

      • 把数据map到一个圆上

      • N台机器按360/N的比例分配数据段

      • 问题:Web server怎么知道谁负责哪一段?从相交数据段的两台机器上migrate数据

        • High Volume Read

        • Data size imbalance 不一定要分配的数据量均匀

      • Consistent Hashing的缺点:和%N的Hashing相比,function比较复杂,维护更难一些

    • 方案三:现实系统中一般采用Micro Shards (Virtual Nodes)

More reads

方案一:Replication (Load Balancer)
  • 例如网站每秒几万次的访问量

  • 方案:多开几台机器,存储相同的data,这样在很多read的时候,分担压力

  • Tradeoff:带来replicate多台机器的write问题

    • 方案:先写入Master Server,再由Master机器写入其它的Slave机器,但是,会有延迟,带来data consistency的问题

      • 问题:Master crashed? 解决:replace by a slave, or double master.

    • 方案:Zookeeper,quorum write,保证所有机器同时得到更新,见Paxos,raft的介绍

方案二:Caching
  • Everywhere

    • Client, Edge/CDN, Datacenter, L1/L2/L3

  • Problem: Hot Post(明星发推)

    • Tool: Memcache 在Memory里做的Cache 减少对DB的queries

    • Memcache Simple API: get(key)-->value, set(key, value, time-to-live)

    • Million Level QPS per box

More writes

k-v pair data --> Memtable(skiplist) --> SS Table(key-sorted --> merge)
write to batching key-sorted
also write to Write Ahead Log
Tiered Write
Big Table
LSM Tree: Log Structured Merge Tree

cassnadra-vs-hbase-4-638.jpg?cb=1366956703

分布式数据库小结

  • 数据量增大

    • 拆数据库

    • Sharding

  • 读操作增多

    • Replication

    • Caching

  • 写操作增多

    • LSM Tree Based Index

SQL vs. NoSQL

分布式数据库解决的问题
  • Scalability

分布式数据库还没解决的问题
  • Query Language

  • Secondary Index

  • ACID Transactions

  • Trust and confidence

阅读 3.4k

Road to Glory
對酒當歌,人生幾何? 譬如朝露,去日苦多。
161 声望
53 粉丝
0 条评论
161 声望
53 粉丝
文章目录
宣传栏