数据库NewSQL之谷歌F1系统

介绍

  谷歌对数据系统性能有极高的要求,MySQL这样的系统都很难令其满意,所以谷歌设计F1数据库,其目标是让其具备高度的可扩展性和高度稳定性,除了必备的SQL语言支持外,F1还提供ad hoc类型查询。

基本构架

  

  用户通过客户端语料库(client library)和F1交互。用户发出的请求首先送到某个F1服务器,F1服务器负责之后的任务分配和数据处理。

  为了减少处理请求造成的延时(latency),F1的客户端和与之直接相连的负载均衡器会首先向最近的F1服务器相连,但是如果附近的F1服务器非常繁忙或者出现故障,那么就会找其他远一点的服务器。

  F1服务器通常和spanner服务器放在一个数据中心,因为这样可以提高数据读写的速度,不过F1服务器也可以连接其他数据中心的spanner服务器。spanner从一个叫做CFS(Colossus File System)的文件系统调取数据,相连的spanner和CFS永远是在同一个数据中心的,也就是说,某个数据中心的spanner不会和另一个数据中心的CFS相连。

  因为F1服务器没有存储数据,F1服务器可以根据访问流量的大小随意增减。

  整个F1系统处理请求可以在单个节点上完成,也可以在多个节点上分布完成,关键看哪个延时更小。如果是用分布式的方式处理请求,F1会指定多个进程(process)来完成,一个从属服务器(slave server)接管一个进程。多个从属服务器由一个主服务器(master server)管理。F1也支持MapReduce。

Spanner

  F1和spanner是同时被研究开发出来的,但是spanner更加偏向于底层处理,例如缓存,数据共享和搬运,数据位置计算等等。

  F1本身是关系型数据库,所以数据是一行一行地放在了列表(table)里。spanner将所有数据分成了一个个由很多行数据组成的集群(cluster),或者叫做目录(directory)。每一个目录至少有一个分段(fragment),大的目录通常有好几个分段。一个目录的多个分段组成了一个组(group),每一个数据中心存放了一个组的副本。

  spanner在处理查询语句的时候使用二阶段锁(two-phase locking)和二阶段提交(two-phase commit),这样信息交互在网络中增加了一倍,增加了延时。为了保证数据的一致性(consistency),spanner使用时间戳(timestamp)给每一条事务排序,保证全球的事务有序执行。

数据模型

  F1的数据模型和关系型数据库相似,都有数据概要(schema),但在此基础上也有扩展。

  F1数据概要下的表格(table)是分层的。子表格(child table)里面的所有key必须包含母表格(parent table)里面的key。根表格(root table)里的每一行叫做根行(root row),所有根据某条根行衍生出来的子表格行组成一个spanner目录

Protocol Buffers

  普通数据库的一个缺点是,数据结构里的数据要通过繁琐的代码转换成数据库数据之后才能被存入数据库,谷歌使用Protocol Buffer语料库(library),使得表格的每一列支持结构化数据类型。

数据索引

  F1有两种索引,一种是局域索引(local index),局域索引的key必须包含根行的key作为前缀。局域索引的key和索引到的结果都和实际的根行放在同一个spanner目录下,所以局域索引的修改占用了事务中很少的一部分用时。

  另一种索引是全局索引(global index)。和局域索引不同的是,全局索引的key不包含根行的key,并且和索引的数据分开存放。很多目录都可以访问全局索引,全局索引存放在多个spanner服务器里。如果修改了一条被索引的行,那么更新索引就需要用到2PC(2 phase commit)。全局索引在扩展性方面做得不是很好。比如说,一个新增1000行数据的事务会让索引新增几百条记录,2PC处理这几百条新增的记录会变得很慢。目前谷歌正在研究让全局索引有更好地扩展性的方法。

修改数据概要(schema)

  F1数据库是一个全球范围的数据库,这意味着世界上所有人都可以修改里面的同一份数据概要,谷歌要求在这个过程中不允许出现任何故障或者表格上锁(table locking)。

  那么如何实现呢?谷歌修改概要的方法是用非同步法,也即是说不同的F1服务器在同一时候可能储存两个本质相同但概要内容不同的数据库。对此,谷歌设计了自己的算法。

事务执行

  F1有三种类型的事务:

  1. 只读(read-only)事务

  2. 直接映射到spanner的事务:此类型的事务直接由spanner处理。

  3. 读写事务:为了防止在读取的时候数据被其他事务修改,F1还会给出上一次被修改的时间,数据一旦被更新,这个时间也会随之更新。

  默认形式下,F1客户端使用读写事务模式。这样做的优点有

  - 读取数据不需要数据锁,而且不会和改写数据相冲突,事务之间互不受影响。

  - 某些事务本来就需要很长时间,这样也不会被禁止

  - 事务在出错之后可以重新执行

  - 客户端在发现远程服务器出现故障后,可以连接另一台服务器

  - 事务执行过程中允许读取处理事务以外的数据

  但是该模式也有缺点,就是如果某一数据被频繁调取,那么系统在这个数据上的工作效率(throughput)就很低。

数据锁

  F1数据库中每一行数据都有一个锁列(lock column)。锁列可以由用户自由定制并且负责该行每一列数据的上锁。这样每一行的不同列就能被不同事务读取修改。

记录修改

  F1需要记录过去对数据库的所有更改。F1记录每一条事务的修改记录时会包含每一行某一列修改前和修改后的值,还有primary key。这里的primary key包含根表格的key和提交事务时候的时间,所有这些记录放在了另外一个表格中。这些记录在F1相关应用中有重要作用。

客户端

  在F1之前,很多谷歌的数据库应用都是用MySQL的ORM,ORM不适合在F1中使用,因为扩展性不高。于是谷歌设计了自己的API。同时F1也支持NoSQL和SQL。

事务查询处理

  F1支持单点事务处理和分布式事务处理,单点OLTP由一个F1服务器处理,分布式OLAP由F1下的从属服务器(slaver)共同处理。

处理远程数据

  在F1中,SQL中的join命令要求读取多个数据中心的数据,这会带来网络延时,解决办法是数据批量传送(batching)和流水线操作(pipelining)。

  数据计算通常是一部分计算好之后就被输出,减少等待时间。这样做的好处是并行高效和减少存储缓冲,但缺点是数据不能被排序。

分布式计算

  每一个事务执行计划包含了几十个子计划,每一个子计划由几个从属服务器执行,同时,数据划分(partitioning)技术也在此处用到。

更多资源(英文)

  F1论文

  相关讲义

时间: 2024-10-01 03:11:46

数据库NewSQL之谷歌F1系统的相关文章

zabbix企业应用之从数据库提取centos 6.2系统在线天数

历史原因造成公司有很多centos 6.2的系统,从某天6.2系统突然自动重启,排查半天发现是6.2的内核bug(超过208天后可能自动重启,可以参考https://access.redhat.com/site/solutions/68466),所以为了不影响业务,在发现6.2系统在线超过180天后就安排重启工作,下面是介绍如何使用zabbix来从数据库里获取6.2系统服务器的在线天数,然后通知业务重启,避免意外重启导致业务受到影响. 1.脚本内容 #!/bin/bash #script nam

安卓项目-利用Sqlite数据库,开发新闻发布系统

本教程致力于程序员可以快速的学习安卓移动端手机开发. 适合于已经习得一种编程语言的同仁. 更多志同道合,想要学习更多编程技术的大神们. 小弟不才,麻烦关注一下我的今日头条号-做全栈攻城狮. 本文章是基于上篇文章基础之上进行深入学习的.程序员带你学习安卓开发-XML文档的创建与解析 Sqlite数据库: Sqlite数据库是在安卓中使用较广泛的数据库.其为简单.轻巧的Sql类文件型数据库.因以简单的文本形式保存,所以安全性不是很高.只要拿到sqlite数据库文件就可以得到数据.所以这就决定了sql

用python3.x与mysql数据库构建简单的爬虫系统(转)

这是在博客园的第一篇文章,由于本人还是一个编程菜鸟,也写不出那些高大上的牛逼文章,这篇文章就是对自己这段时间学习python的一个总结吧. 众所周知python是一门对初学编程的人相当友好的编程语言,就像本屌丝一样,一学就对它产生好感了!当然,想要精通它还有很多东西需要学习.那废话不多说了,下面我就来说一下如何用python3.x与mysql数据库构建一个简单的爬虫系统(其实就是把从网页上爬下来的内容存储到mysql数据库中). 首先就是搭建环境了,这里就简介绍一下我的环境吧.本机的操作系统是w

winfrom 导入Excel表到access数据库(来自小抽奖系统)

网上有很多这种方法,本人只是针对自己的系统来实现的 //导入excel表 private void ImportTSMenu_Click(object sender, EventArgs e) { OpenFileDialog openFD = new OpenFileDialog(); openFD.Filter = "Excel文件|*.xls"; if (openFD.ShowDialog(this.Owner) == DialogResult.OK) { string strF

MySQL数据库系列之Centos6.5系统下RPM包安装MySQL5.6

查看操作系统相关信息. [[email protected]_db1 ~]# cat /etc/issue CentOS release 6.5 (Final) Kernel \r on an \m [[email protected]_db1 ~]# uname -a Linux bj_db1 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 22 03:15:09 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux 2.创建需要下载rpm软

数据库设计:用户登录系统数据库表设计

用户登录系统数据库表设计 最近看了看公司后台用户登录系统的设计, 比较混乱, 主要还是因为URS和Oauth以及URS第三方这三个登录形式各不相同导致的. 下面着重介绍一下涉及到第三方登录中需要注意的问题 在一个新项目中, 如果是要建立自己的登录体系的话, 那么直接创建一个Users表,包含username和password两列,这样,就可以实现登录了: id | username | password | name等其他字段 ----+----------+----------+-------

安卓开发数据库,调用谷歌内部API指令

使用这种方式调用数据库,比常规方式好在,简洁且具有返回值,可以判断是否成功 add: SQLiteDatabase db=myOpenHelper.getWritableDatabase(); ContentValues values=new ContentValues(); values.put("username", "wangwu"); values.put("password", "110"); long insert

php5.6配置oracle数据库扩展 oci8(windows7系统64位)

1.去http://pecl.php.net/package/oci8 php官方扩展库下载扩展 http://pecl.php.net/package/oci8/2.0.8/windows 查看phpinfo()可以知道需要下载哪种版本的扩展 2.编辑php.ini文件引入oci8扩展 3.下载对应版本的oracle 客户端,并放到c盘目录,把路径放到环境变量,重启电脑 http://www.oracle.com/technetwork/topics/winsoft-085727.html  

(转载)数据库表设计-水电费缴费系统(oracle)

水电缴费管理系统数据表设计 SQL建表脚本: 1 --建表 2 --管理人员表 admin 3 create table admin( 4 admin_id varchar2(3) not null, 5 admin_loginname varchar2(8) not null, 6 admin_password varchar2(6) not null, 7 admin_username varchar2(4) not null, 8 constraint pk_admin primary k