# F1: A Distributed SQL Database That Scales 构建在spanner上, 提供`synchronous cross-datacenter replication`和强一致性. 同步复制带来的高`commit`延时, 通过数据模型的结构特点缓解(how?). - 目标/挑战 - 扩展性 - 很多复杂查询(join,), 对shard策略要求高 - 高可用 - 一致性 - ACID - 易用性 - 完全兼容sql ## 架构 - client就近连接相同dc的F1 server - 依赖spanner进行跨dc的通信 - CFS做本地存储 - F1 server基本无状态 - 除了client拿到悲观锁时, 事务期间, 这个client会始终访问开始事务时的F1 server. - query planner 还会评估请求是否应该分布式执行.(是否会降低请求处理时间) - 扩展 - 加Spanner server - 会导致数据重分布, 但是对F1/client透明 - 加F1 server - 加F1 slave - spanner跨机房的平均延时(50 ~ 150ms) - spanner - 数据组织 - `Group`, 复制的基本单位, `paxos`算法做复制. 副本叫`tablet`. 所有写(tx)都在paxos选出的leader上进行.可能有只读副本, 不参与选举. - `Fragment` - `Directory` - `Row` - 事务 - 乐观事务 - 相同group事务 - 跨group事务 - 2pc-commit - 时序 - `globally safe timestamp` ## 数据模型 支持Hierachical Schema, 模型定义时, 可以继承父模型, 父模型的字段会插入子模型中. 类似于一些`orm`(sqlalchemy), 中定义类, 子类最终形成表的逻辑. - `Customer(customerId)` - `Campaign(customerId, campaignId)` - `AdGroup(customerId, campaignId, adGroupId)` 好处是可以提高部分查询的并行度, 例如`Campaign.FindByCustomerId(xx)`, 可以并行查询`customer`和`campaign`, 因为customerId相同. 另外层级结构, 是的一些相同祖先的数据操作, 可以集中在spanner的一个group上,避免了跨group的2pc过程. 列支持pb格式, (支持pb结构内查询么? 支持构建索引时从pb里抽字段) ### 索引 F1索引有两种物理布局: (这里local,global主要是区分spanner机器) - `local` - 必须包含根节点id - `(customerId, keyword)` - 保证这些index存到相同的spanner机器 - `global` - 不用包含根节点id - 会导致大的事务无法完成, 因为对index的变更需要非常多的2pc参与者,导致无法协商完成. ## schema变更