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
分布式数据库小结
-
数据量增大
拆数据库
Sharding
-
读操作增多
Replication
Caching
-
写操作增多
LSM Tree Based Index
SQL vs. NoSQL
分布式数据库解决的问题
Scalability
分布式数据库还没解决的问题
Query Language
Secondary Index
ACID Transactions
Trust and confidence