123
 123

Tip: 看不到本站引用 Flickr 的图片? 下载 Firefox Access Flickr 插件 | AD: 订阅 DBA notes --

2010-06-07 Mon

18:42 Oracle Index Merge 与 and_equal 的变迁 (11118 Bytes) » Oracle Life

作者:eygle 发布在 eygle.com

and_equal是Oracle支持的一种特定操作,可以将多个单列索引进行合并(Index Merge)输出查询结果。
同时and_equal可以通过Hints来进行强制,最少指定两个索引,最多指定5个。

以下的执行计划是常见的and_equal执行方式:
SQL> select /*+ and_equal(t1 iu ii) */  username,password from t1 where username='EYGLE' and user_id=58;

USERNAME                       PASSWORD
------------------------------ ------------------------------
EYGLE                          B726E09FE21F8E83


执行计划
----------------------------------------------------------
Plan hash value: 1425017857

------------------------------------------------------------------------------------
| Id  | Operation                   | Name | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |      |     1 |    47 |     2   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS BY INDEX ROWID| T1   |     1 |    47 |     2   (0)| 00:00:01 |
|   2 |   AND-EQUAL                 |      |       |       |            |          |
|*  3 |    INDEX RANGE SCAN         | II   |     1 |       |     1   (0)| 00:00:01 |
|*  4 |    INDEX RANGE SCAN         | IU   |     1 |       |     1   (0)| 00:00:01 |
------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("USERNAME"='EYGLE' AND "USER_ID"=58)
   3 - access("USER_ID"=58)
   4 - access("USERNAME"='EYGLE')
但是从Oracle 10g开始,and_equal操作被废弃(depricated)掉,Oracle不再支持。这里废弃的含义并不是被彻底移除,而是说不再进行改进,通过hints仍然可以强制实现Index Merge的and_equal操作。

以上的输出就是来自Oracle 10.2.0.4,在使用rule提示时,Oracle会主动选择and_equal,所以不再支持是因为,这种方法限制过多,而且远不如复合索引来的灵活:
SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Prod
PL/SQL Release 10.2.0.4.0 - Production
CORE    10.2.0.4.0      Production
TNS for 32-bit Windows: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production


SQL> select /*+ rule */  username,password from t1 where username='EYGLE' and user_id=58;

USERNAME                       PASSWORD
------------------------------ ------------------------------
EYGLE                          B726E09FE21F8E83


执行计划
----------------------------------------------------------
Plan hash value: 3072843751

--------------------------------------------
| Id  | Operation                   | Name |
--------------------------------------------
|   0 | SELECT STATEMENT            |      |
|   1 |  TABLE ACCESS BY INDEX ROWID| T1   |
|   2 |   AND-EQUAL                 |      |
|*  3 |    INDEX RANGE SCAN         | IU   |
|*  4 |    INDEX RANGE SCAN         | II   |
--------------------------------------------
新的可选替代方案是NDEX_COMBINE,从9i开始,初始化参数 _b_tree_bitmap_plans设置为true,允许为B*Tree索引使用,bitmap convert:
SQL> select /*+ index_combine(t1 iu ii) */  username,password from t1 where username='EYGLE' and user_id=58;

USERNAME                       PASSWORD
------------------------------ ------------------------------
EYGLE                          B726E09FE21F8E83


执行计划
----------------------------------------------------------
Plan hash value: 1808973554

-----------------------------------------------------------------------------------------
| Id  | Operation                        | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                 |      |     1 |    47 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID     | T1   |     1 |    47 |     2   (0)| 00:00:01 |
|   2 |   BITMAP CONVERSION TO ROWIDS    |      |       |       |            |          |
|   3 |    BITMAP AND                    |      |       |       |            |          |
|   4 |     BITMAP CONVERSION FROM ROWIDS|      |       |       |            |          |
|*  5 |      INDEX RANGE SCAN            | II   |       |       |     1   (0)| 00:00:01 |
|   6 |     BITMAP CONVERSION FROM ROWIDS|      |       |       |            |          |
|*  7 |      INDEX RANGE SCAN            | IU   |       |       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   5 - access("USER_ID"=58)
   7 - access("USERNAME"='EYGLE')


相关文章|Related Articles

评论数量(0)|Add Comments

本文网址:

15:14 Performance Optimization and Six Sigma (6243 Bytes) » MySQL Performance Blog

You might be familiar with Six Sigma business management strategy which is employed by variety of the companies in relationship to managing quality of its product. Six Sigma applies to number of defects – when you have reached six sigma quality in your production you would see 99.99966% of the products manufactured with no defects, or in other words there is less than 3 defects per million.

One of principles of six sigma is what customers tend to be concerned about variance a lot more than average. For example if you produce tomato soup and the average difference from declared weight is going to be 0.1 gram or 0.5 gram, probably nobody would not notice the difference. What would worry people however is significant number of very large differences, such as half empty tomato soup can.

You can see Apdex standard looking among similar lines, which is looking to classify user experiences as good, tolerable and not acceptable.

So how are doing with this in MySQL (and general Web performance management) ? Not So good. In most cases organizations focus on performance rather than performance stability even though it is the later what their users really care about. Consider Adaptive Checkpoint in Innodb for example – until it got implemented we had very poor performance stability under very large number of workloads. Look at the industry standard TPC-C benchmark for example – it defines the guidance for response time as ninety five percentile response time, which is just two sigma in sigma notation. A lot of popular tools, including Sysbench and Maatkit also use 95% response time (probably inherited from these industry standards).
Sometimes we use 99% response time as a guidance but this is not even quite 3 sigma which would be 99.7%.

One reason we use rather weak confidence intervals in performance optimization is we need a lot of transactions to get stable measurements for stronger ones. If we’re looking at 95 percentile something like 1000 transactions will give more or less stable results in most cases. If we’re looking at 99 percentile we would need at least 10.000 and I’d look for at least 100.000 to get stable 99.9% response time.

In number of my talks about performance measurements I suggested to measure 95 percentile over short period of times for example every minute, which is great for graphing and it is somewhat gives you higher confidence if you look at the whole day. I believe meeting 95 percentile response time every minute of the day is a lot harder than getting 99 percentile over 24 hours.

It is worth to mention modern applications become a lot more demanding to stable performance. In the past you would have only one request to get HTML which would be responsible for most information on the page. Now with technologies like AJAX there can be number of request during page generation and interaction and each of them being slow give sluggish experience to the user.

So what can we do in terms of performance management ? Start measuring much higher response time and allow for less variance. Why not to starve at least for 99.9 daily response time (one request per thousand being slow) and use 99 percentile over 5 minutes to graph response time stability. This is still very far from the confidence manufacturing uses. This is also what is probably practical for most of internet applications – A lot of applications like Gmail have 99.9 to 99.99 percent of uptime, and from the user point of view the percentile number for good response time is bound by availability figure.

I also would like to see the technology vendors would focus more on the performance stability in their benchmarks. Way too often you just see the Throughput number reported which gives zero information about performance stability and so is completely irrelevant to ability of the product to provide great user experience.


Entry posted by peter | 3 comments

Add to: delicious | digg | reddit | netscape | Google Bookmarks

07:53 Base: 一种Acid的替代方案 (19703 Bytes) » dbthink

本文是Ebay的架构师在2008年发表给ACM的文章,是一篇解释BASE原则,或者说最终一致性的经典文章. 文中Dan讨论了BASE与ACID原则的基本差异, 以及如何设计大型网站以满足不断增长的可伸缩性需求,期间如何对业务做调整与折衷. 以及一些具体的折衷技术的介绍.

原文链接: BASE: An Acid Alternative
Pdf下载链接: Base

在对数据库进行分区后,为了可用性(Availability)牺牲部分一致性(Consistency)可以显著的提升系统的可伸缩性(Scalability).

By DAN PRITCHETT, EBAY ,Translated by Jametong

Web应用在过去10年变得越来越普及.无论是为最终用户还是为应用开发者构建的应用,对这个应用的希望很可能都是,此应用被最广泛的用户使用-广泛的使用会带来交易的增长.业务如果依赖于持久化,数据存储就很可能成为瓶颈.

扩展任何应用都有两种策略.第一种,也是最简单的一种,就是纵向扩展:将应用迁移到更大更强的计算机上. 目前可用的最大的机器也满足不了它的容量是它最明显的限制.纵向扩展也很昂贵,增加交易容量通常都需要购买下一个更大的机器.纵向扩展通常还会产生对供应商的依赖,从而进一步增加成本.

横向扩展(Horizontal Scaling)提供了更多的灵活性,但也会显著的增加复杂度.横向数据扩展可能沿着两个方向发展.按功能扩展(Functional Scaling)牵涉到按功能对数据进行分组,并将不同的功能组分布在多个不同的数据库上.在功能内部将数据拆分到多个数据库上,也就是进行分片(Sharding),它为横向扩展增加一个新的维度.图-1简要阐释了横向数据扩展策略.

如图-1所示,横向扩展的两种方法可以同时进行运用.用户信息(Users)、产品信息(Products)与交易信息(Transactions)可以存储在不同的数据库中.另外,每个功能区域根据其交易容量(transactional capacity)可以再拆分到多个数据库中.如图所示,功能区域可以相互独立地进行扩展.

功能分区(Functional Partitioning)

功能分区对于实现高可伸缩性相当重要.每一种好的数据库架构都会根据功能将概要(Schema)分解到多张表中.用户(Users)、产品(Products)、交易(Transactions)以及通讯都是功能分区的例子. 常用的方法是,利用诸如外键(foreign key)一类的数据库概念来维持这些功能区域之间的数据一致性.

依赖数据库的约束保证功能组之间的一致性,会导致数据库的不同概要(schema)在部署策略上高度耦合.要支持约束,表必须存在单一的数据库服务器上,当交易率(transaction rate)增长时也无法对其进行横向扩展.很多情况下, 将数据的不同功能组迁移到相互独立的数据库服务器上是最容易实现的向外扩展(Scale-out)方案.

可扩展到非常高的交易量的概要会将不同的功能的数据放置在不同的数据库服务器上.这需要将数据之间的约束从数据库迁移到应用中去. 同时这也将引入一些新的挑战,本文的后续内容会对此进行深入探讨.

CAP定理(CAP Theorem)

Eric Brewer,一位加州大学伯克利分校的教授,Inktomi公司的共同创办人以及首席科学家,作出了以下推测,Web服务无法同时满足以下3个属性(由其首字母构成缩写CAP):

  • 一致性(Consistency).客户端知道一系列的操作都会同时发生(生效).
  • 可用性(Availability).每个操作都必须以可预期的响应结束.
  • 分区容错性(Partition tolerance).即使出现单个组件无法可用,操作依然可以完成.

具体地讲,在任何数据库设计中,一个Web应用至多只能同时支持上面的两个属性.显然,任何横向扩展策略都要依赖于数据分区;因此,设计人员必须在一致性与可用性之间做出选择.

ACID解决方案

ACID数据库事务极大地简化了应用开发人员的工作.正如其缩写标识所示,ACID事务提供以下几种保证:

  • 原子性(Atomicity).事务中的所有操作,要么全部成功,要么全部不做.
  • 一致性(Consistency).在事务开始与结束时,数据库处于一致状态.
  • 隔离性(Isolation). 事务如同只有这一个操作在被数据库所执行一样.
  • 持久性(Durability). 在事务结束时,此操作将不可逆转.(也就是只要事务提交,系统将保证数据不会丢失,即使出现系统Crash,译者补充).

数据库厂商在很久以前就认识到数据库分区的必要性,并引入了一种称为2PC(两阶段提交)的技术来提供跨越多个数据库实例的ACID保证.这个协议分为以下两个阶段:

  • 第一阶段,事务协调器要求每个涉及到事务的数据库预提交(precommit)此操作,并反映是否可以提交.
  • 第二阶段,事务协调器要求每个数据库提交数据.

如果有任何一个数据库否决此次提交,那么所有数据库都会被要求回滚它们在此事务中的那部分信息.这样做的缺陷是什么呢? 我们可以在分区之间获得一致性.如果Brewer的猜测是对的,那么我们一定会影响到可用性,但,怎么可以这样呢?

任何系统的可用性都是执行操作的相关组件的可用性的产物.此陈述的后半段尤其重要.系统中可能会使用但又不是必需的组件,不会降低系统的可用性.在两阶段提交中涉及到两个数据库的事务,它的可用性是这两个数据库中每一个的可用性的产物.例如,如果我们假设每个数据库都有为99.9%的可用性,那么这个事务的可用性就是99.8%,或者说每月43分钟的额外停机时间.

一种ACID的替代方案

如果ACID为分区的数据库提供一致性的选择,那么你如何实现可用性呢?答案是BASE(基本上可用、软(弱)状态、最终一致性).
BASE与ACID截然相反.ACID比较悲观,在每个操作结束时都强制保持一致性,而BASE比较乐观,接受数据库的一致性处于一种动荡不定的状态.虽然,听起来很难应付,实际上这相当好管理,并且可带来ACID无法企及的更高级别的可伸缩性.

BASE的可用性是通过支持局部故障而不是系统全局故障来实现的.下面是一个简单的例子:如果用户分区在5个数据库服务器上,BASE设计鼓励类似的处理方式,这样一个用户数据库的故障只会影响这台特定主机上的那20%的用户.这里不涉及任何魔法,不过,它确实可以带来更高的可感知的系统可用性.

因此,到目前为止,你已经将数据分解到了多个功能组中,并将最繁忙的功能组分区到了多个数据库中,如何在你的应用中应用BASE原则呢?与ACID的典型应用场景相比,BASE需要对逻辑事务中的操作进行更加深入的分析.到底该如何进行分析呢?后续的内容将提供部分指导原则.

一致性模式(Consistency Patterns)

沿着Brewer的猜测,如果BASE在分区数据库中选择保留可用性(Availability), 那么,弱化一定程度的一致性就成为必然的选择.这通常难以决策,因为商业投资方与开发人员都倾向于认为一致性(Consistency)对应用的成功至关重要.哪怕是临时的不一致也瞒不过最终用户,因此,技术部门与产品部门都需要参与进来,以决定将一致性弱化到什么程度.

图-2是一个简单的概要,它阐释了BASE中一致性要考虑的事情.用户表存储用户信息,同时还包含总销售额与总购买额.这些都是运行时的统计.交易表存储每一笔交易,将买家、卖家以及交易金额关联在一起.这些是对实际使用的表进行过度简化后的结果,不过,它已经包含阐释一致性的多个方面的必要元素.

一般来说,功能组之间的一致性要比功能组内部的一致性要更加容易弱化.这个示例概要包含两个功能组:用户与交易.每当售出一个条目(的商品),交易表中就会增加一条记录,买家与卖家的计数器都会被更新.使用ACID风格的事务,SQL语句可能如图-3所示.

用户表中的总销售额的列与总购买额的列可以被认为是交易表的一份缓存(Cache).它的存在是为了提高系统的效率.有鉴于此,一致性的约束可以被弱化. 可以调整一下买家与卖家的期望设置,从而他们的运行结余(running balance)不能立即反映交易的结果.这种情况很常见,实际上,人们经常会遇到交易与运行结余之间的这种延迟(例如,ATM取款或者手机通话).

如何修改SQL语句来弱化一致性要取决于如何定义运行结余,如果它们只是简单的估计,也就是部分交易可以被错过不统计,SQL的修改非常简单,如图-4所示.

现在,我们已经将对用户表与交易表的更新做了解耦.两个表之间的一致性将再也无法保证.实际上,在第一个事务与第二个事务处理间隔发生故障,将导致用户表持久处于不一致的状态,不过,如果合同约定运行时汇总(running total)是估计值的话,这样做也足够了.

如果无法接受估计值,该怎么办呢?如何继续对用户表与交易表的更新进行解耦呢?引入一个持久消息队列来解决此问题. 有多种选择可以实现持久消息.然而,实现此消息队列的最关键的因素是,确保队列的持久化支持与数据库使用同样的资源.要实现队列在不涉及2PC的情况下按事务提交,这样做很有必要 .现在的SQL操作看上看去有点不同了,如图-5所示.

这个例子中的语法有点随意,为了阐释概念对其逻辑也做了大量的简化.通过在插入语句的同一个事务中对持久消息进行排队,可以抓取更新用户运行结余所需的信息.这个事务包含在同一个数据库实例中,因此,它不会影响系统的可用性.

一个独立的消息处理组件,会从队列中取出每条消息,并将此信息应用到用户表.这个例子看似解决了所有的问题,但是,还有一个问题没有解决.为了避免排队时发生2PC,消息是持久化在交易的主机上的.如果在涉及到用户主机的事务中从队列中取出消息,我们仍将遇到2PC的情景.

消息处理组件中的2PC的一种解决方案是什么都不做.通过将更新操作解耦到一个独立的后端(back-end)组件,可以保持面向客户的组件的可用性.业务需要或许可以接受较低的消息处理器的可用性.

不过,假定你的系统完全无法接受2PC.这个问题该如何解决呢?首先,你需要理解等幂概念.如果一个操作被应用一次或多次都能取得同样的结果,就被认为是等幂的.等幂操作非常有用,因为它们允许局部故障,重复执行它们不会改变系统的最终状态.

从等幂的角度看,所选的这个例子是有问题的.更新操作通常不等幂.这个例子中有累加账户列的操作.重复应用此操作显然会导致错误的账户余额.然而,即使是仅仅设定一个值的更新操作也不是等幂的,因为它还涉及到操作执行的顺序.如果系统无法保证更新操作按照接收到的顺序被应用,系统的最终状态也将是不正确的.后面的内容会进一步讨论此问题.

在账户更新的例子中,你需要一种方式来跟踪哪些更新已经应用成功,哪些更新仍然未解决.一种技术是,使用一个表来记录已经应用的那些交易的唯一识别号.

图-6中展示的表会记录交易ID、更新了哪个帐号以及应用此帐号的用户ID.现在,我们的样本伪代码如图-7所示.


这个例子取决于可以窥视队列中的一条消息,并在成功处理后立即删除此消息.如有必要,可以通过两个独立的事务来处理它:消息队列上一个事务,用户数据库上一个事务.数据库操作成功提交,才提交队列操作.目前的算法可以支持局部故障,而且又能提供不依赖于2PC的事务保证.

如果只是关注更新的顺序的话,还有一个更加简单的技术可以确保等幂更新.我们来稍微调整一下我们的示例概要,来阐释面临的挑战以及相应的解决方案(见图-8).

假设两笔购买交易在一个很短的时间窗口内发生,我们的消息系统无法确保顺序操作.您现在面临的情况是,取决于消息被处理的顺序,last_purchase可能出现一个不正确的值.幸运的是,可以通过对SQL语句做点简单调整来解决此类更新问题, 如图-9所描述.

仅仅通过不允许last_purchase时间做逆向调整,就可以做到更新操作顺序不相关.也可以通过这种方法来保护任何更新免遭无序更新(out-of-order update).你还可以尝试使用单调递增的事务ID来取代时间.

消息队列的顺序

关于顺序消息投递,下面这个简短地附属说明可能有用.消息系统可以提供确保消息发送的顺序与接收的顺序一致的能力.不过,支持此功能可能非常昂贵,通常也没有必要,实际上,有时它也只是给出了一种虚假的安全感.

这里提供的例子阐释了如何弱化消息的顺序,并在最终仍然能够提供一个数据库的一致性视图.弱化消息排序所需的开销是名义上的,在大部分情况下,此开销要显著的少于在消息系统中确保消息顺序的开销.

进一步讲,无论互动风格如何,Web应用在语义上都是一个事件驱动的系统.客户端请求以任意顺序达到系统.每个请求所需的处理时间要求也各不相同.整个系统的不同组件的请求调度也是不确定的,导致了消息排队的不确定.要求保持消息的顺序给出的是一种虚假的安全感.简单的事实是,不确定的输入会导致不确定的输出.

弱状态/最终一致性(Soft State/Eventually Consistent)

到此为止,重点一直是为了可用性而权衡牺牲部分一致性.硬币的另外一面是,理解软状态与最终一致性对应用设计有何影响.
由于软件工程师倾向于认为系统是闭环(closed loop)的.从预见投入产生预见的产出方面讲,我们可以这样考虑他们行为的可预测性.这对于创建正确的软件系统非常必要.好的消息是,在大部分情况下使用BASE不会改变一个闭环系统的可预测性,不过,它确实需要从整体上来进行审视.

一个简单的例子就可以帮助解释这一点.考虑这样一个系统,用户可以在此将资产转移给另一个用户.哪种类型的资产都没有关系,它可以是钱或者游戏中的装备.对于这个例子,我们假设,已经通过使用一个用于解耦的消息队列,对如下两个操作进行了解耦:从一个用户取出资产,将资产给另一个用户.

很快,系统就会感觉到有问题与不确定性.在资产离开一个用户到达另一个用户中间,有一段时间的延时. 这个时间窗口的大小由消息系统的设计所决定.无论如何,在开始状态与结束状态之间,始终会有一个时间间隔,在这段时间内, 看似任何用户都不享有这笔资产.

不过,如果我们从用户的视角来考虑这个问题,这个时间间隔可能就是无所谓的或者根本就不存在.无论是接收的用户还是发出的用户可能都不知道资产将在何时到达.如果在发送与接收之间的时间间隔是几秒钟,对于具体沟通资产转移的用户来讲,它将是隐蔽的或确实可以忍受的.在这种状况下,这种系统行为对用户来讲,就是一致并可接受的,即使,我们在实现中依赖了软状态以及最终一致性.

事件驱动架构(Event-Driven Architecture)

如果你确实需要知道,系统将在何时达到一致的状态?你可能需要一种算法,来应用到这个状态上,不过,仅仅在它达到一个与后续请求相关的一致状态时才会被应用.

继续讨论前面的例子,如果在资产到达时,需要通知用户,怎么办? 在将资产交付给接收用户的那个事务内创建一个事件,就可以提供一种机制,当达到一个事先确定的状态时,可以做进一步的处理.EDA(事件驱动架构,Event-Driven Architecture)可以显著改善可伸缩性以及架构的解耦.对于EDA应用的进一步讨论超出了本文的范畴.

结论

显著的扩展系统的交易率,需要以一种全新的方式来考虑如何对资源进行管理.当负载需要分布到大量的组件上时,传统的事务模型会漏洞百出.对操作进行解耦,并依次对它们进行处理,可能提供更好的可用性与伸缩性,不过是以牺牲一致性为代价.BASE提供了一种模型来考虑这种解耦.

References

Dan Pritchett是Ebay的一位技术人员,他过去4年一直是Ebay架构团队的成员.在此岗位上,他与Ebay市场部、Paypal以及Skype的战略、商业、产品与技术团队进行合作.他已经有20年技术公司的工作经历,他服务过的公司包含Sun,HP以及硅谷图形公司(Silicon Graphics),Pritchett具有丰富的技术经历,从网络层协议与操作系统到系统设计与软件模式.他拥有密苏里州Rolla大学的计算机科学学士学位.

No related posts.

04:11 探索Google App Engine背后的奥秘(2)--Google的整体架构猜想 (13905 Bytes) » DBA Notes

作者:ikewu 发布在 dbanotes.net. BLOG 墙外订阅数量,点击则可进行订阅

按:此为客座博文系列。投稿人吴朱华曾在IBM中国研究院从事与云计算相关的研究,现在则致力于云计算技术。

本文是基于现有的公开资料和个人的经验来对Google的整体架构进行总结和猜想。

在软件工程界,大家有一个共识,那就是"需求决定架构",也就是说,架构的发展是为了更好地支撑应用。那么本文在介绍架构之前,先介绍一下Google所提供的主要产品有哪些?

产品

对于Google和它几个主要产品,比如搜索和邮件等,大家已经非常熟悉了,但是其提供服务的不只于此,并主要可分为六大类:

  • 各种搜索:网页搜索,图片搜索和视频搜索等。
  • 广告系统:AdWords和AdSense。
  • 生产力工具:Gmail和Google Apps等。
  • 地理产品:地图,Google Earth和Google Sky等。
  • 视频播放:Youtube。
  • PaaS平台:Google App Engine。

设计理念

根据现有的资料,Google的设计理念主要可以总结出下面这六条:

  • Scale,Scale,Scale Scale:因为Google大多数服务所面对的客户都是百万级别以上的,导致Scale也就是伸缩已经深深植入Google的DNA中,而且Google为了帮助其开发人员更好地开发分布式应用和服务,不仅研发了用于大规模数据处理MapReduce框架,还推出了用于部署分布式应用的PaaS平台Google App Engine。
  • 容错:一个分布式系统,就算是构建在昂贵的小型机或者大型机之上,也会不时地出现软件或者硬件方面的错误,何况Google的分布式系统还是浇筑在便宜的X86服务器之上,即使其设备标称的MTBF(平均故障间隔时间)很高,但是由于一个集群内的设备极多,导致其错误发生的几率非常高,比如李开复曾经提过这样一个例子:在一个拥有两万台X86服务器的集群中,每天大约有110台机器会出现宕机等恶劣情况,所以容错是一个不可被忽视的问题,同时这点也被Google院士Jeffrey Dean在多次演讲中提到。
  • 低延迟:延迟是影响用户体验的一个非常重要的因素,Google的副总裁Marissa Mayer曾经说过:"如果每次搜索的时间多延迟半秒的话,那么使用搜索服务的人将减少20%",从这个例子可以看出,低延迟对用户体验非常关键,而且为了避免光速和复杂网络环境造成的延时,Google已在很多地区设置了本地的数据中心。
  • 廉价的硬件和软件:由于Google每天所处理的数据和请求在规模上是史无前例的,所以现有的服务器和商业软件厂商是很难为Google"度身定做"一套分布式系统,而且就算能够设计和生产出来,其价格也是Google所无法承受的,所以其上百万台服务器基本采用便宜的X86系统和开源的Linux,并开发了一整套分布式软件栈,其中就包括上篇提到的MapReduce,BigTable和GFS等。
  • 优先移动计算:虽然随着摩尔定律的不断发展,使得很多资源都处于不断地增长中,比如带宽等,但是到现在为止移动数据成本远大于移动计算的成本,所以在处理大规模数据的时候,Google还是倾向于移动计算,而不是移动数据。
  • 服务模式:在Google的系统中,服务是相当常用的,比如其核心的搜索引擎需要依赖700-1000个内部服务,而且服务这种松耦合的开发模式在测试,开发和扩展等方面都有优势,因为它适合小团队开发,并且便于测试。

整体架构的猜想

在整体架构这部分,首先会举出Google的三种主要工作负载,接着会试着对数据中心进行分类,最后会做一下总结。

三种工作负载

对于Google而言,其实工作负载并不仅仅只有搜索这一种,主要可以被分为三大类:

  • 本地交互:用于在用户本地为其提供基本的Google服务,比如网页搜索等,但会将内容的生成和管理工作移交给下面的内容交付系统,比如:生成搜索所需的Index等。通过本地交互,能让用户减少延迟,从而提高用户体验,而且其对SLA要求很高,因为是直接面对客户的。
  • 内容交付:用于为Google大多数服务提供内容的存储,生成和管理工作,比如创建搜索所需的Index,存储YouTube的视频和GMail的数据等,而且内容交互系统主要基于Google自己开发那套分布式软件栈。还有,这套系统非常重视吞吐量和成本,而不是SLA。
  • 关键业务:主要包括Google一些企业级事务,比如用于企业日常运行的客户管理和人力资源等系统和赚取利润的广告系统(AdWords和AdSense),同时关键业务对SLA的要求非常高。

两类数据中心

按照2008年数据,Google在全球有37个数据中心,其中19个在美国,12个在欧洲,3个在亚洲(北京、香港、东京),另外3个分布于俄罗斯和南美。下图显示其中36个数据中心在全球的分布:

pingdom_google_map_worldwide.jpg 图1. 2008年Google全球数据中心分布图

根据 Jeffrey Dean 在2009年末的一次演讲和最近几期季报可以推测出Google并没有在2009年过多地增加全球数据中心的数量,总数应该还是稍多于36个,但很有可能在台湾、马来西亚、立陶宛等地增加新的数据中心。

虽然Google拥有数据中心数量很多,但是它们之间存在一定的差异,而且主要可以分为两类:其一是巨型数据中心,其二是大中型数据中心。

巨型数据中心:服务器规模应该在十万台以上,常坐落于发电厂旁以获得更廉价的能源,主要用于Google内部服务,也就是内容交付服务,而且在设计方面主要关注成本和吞吐量,所以引入了大量的定制硬件和软件,来减低PUE并提升处理量,但其对SLA方面要求不是特别严厉,只要保证绝大部分时间可用即可。下图是Google巨型数据中心的一个代表,这个数据中心位于美国俄勒冈州北部哥伦比亚河畔的Dalles市,总占地面积接近30英亩,并占用了附近一个1.8GW水力发电站的大部分电力输出,当这个数据中心全部投入使用后,将消耗103兆瓦的电力,这相当于一个中小型城市的整个生活用电。

google DC.jpg

图2. Google在美国俄勒冈州哥伦比亚河畔的巨型数据中心近景图

大中型数据中心:服务器规模在千台至万台左右,可用于本地交互或者关键业务,在设计方面上非常重视延迟和高可用性,使得其坐落地点尽可能地接近用户而且采用了标准硬件和软件,比如Dell的服务器和MySQL的数据库等,常见的PUE大概在1.5和1.9之间。本来坐落于北京朝阳区酒仙桥附近的"世纪互联"机房的Google中国数据中心也属于大中型数据中心这类,其采用的硬件有DELL的工作站和Juniper的防火墙等,下图为其一角。

2008421124418.jpg

图3. Google前中国数据中心的一角(参[26])

关于两者的区别:具体请查看下表:

  巨型数据中心 大中型数据中心
工作负载 内容交付 本地交互/关键业务
地点 离发电厂近 离用户近
设计特点 高吞吐,低成本 低延迟,高可用性
服务器定制化
SLA 普通
服务器数量 十万台以上 千台以上
数据中心数量 十个以内 几十个
PUE估值 1.2 1.5

表1. 巨型与大中型数据中心的对比表

总结

最后,稍微总结一下,首先,普通的用户当访问Google服务时,大多会根据其请求的IP地址或者其所属的ISP将这个请求转发到用户本地的数据中心,如果本地数据中心无法处理这个请求,它很有可能将这个请求转发给远端的内容交互中心。其次,当广告客户想接入Google的广告系统时,这个请求会直接转发至其专业的关键业务数据中心来处理。

google architecture.PNG

图4. 总结

因为本文是基于现有的公开资料和个人的经验的总结和猜想,所以和Google实际的运行情况没有任何联系。

本篇结束,下篇将对Google App Engine及其主要组成部分进行介绍。

--EOF--


最近文章|Recent Articles

本站赞助商:豆瓣网

评论数(1)|添加评论 | 最近作者还说了什么? Follow Fenng@Twitter
本文网址:

DBA Notes 理念: 用简约的技术取得最大的收益...

01:53 Installing Oracle11gR2 on Solaris10 (2561 Bytes) » Chanel [K]

实际上Oracle11gR2真的在安装上花了不少心思,虽然目前在除了Linux平台的其它操作系统上都还有这样那样的小问题,但是确实已经很方便了。

如果要在Solaris10中安装Oracle11gR2的单机数据库,只需要以下简单的步骤。

1. 保证/tmp文件系统大于1G
在Soalris10中默认/tmp使用的是swap空间,因此在安装操作系统的时候给swap足够大的空间,比如4G或者8G

2. 添加组和用户(只需要最简单的dba组)

# groupadd dba
# useradd -g dba -d /export/home/oracle -m oracle

3. 修改操作系统内核参数(只需要修改shmmax,这里修改为4G)

# projadd -U oracle -K \
  "project.max-shm-memory=(priv,4096MB,deny)" user.oracle

4. 使用磁盘c1t1d0和c1t2d0创建zfs文件系统(ZFS非常方便,自动mount,不再需要修改vfstab文件)

# zpool create orapool c1t1d0 c1t2d0
# zfs set mountpoint=/oracle orapool

5. runInstaller

6. 安装完毕以后再去设置oracle用户的.profile环境变量


2010-06-06 Sun

21:06 Security Enhanced PostgreSQL (4275 Bytes) » DBA@SKY-MOBI
当前,越来越多的应用程序使用到数据库的场景越来越多,使用数据库作为动态信息的保存等等。在这样的复杂环境下面,仅仅考虑单个组件的安全是不够的,应该考虑到全局的安全策略一致。2010年5月份举行的全球PostgreSQL数据库讨论大会就数据安全这个类别有专门的演讲《A secure web-application stack using SE-PostgreSQL》。包括将要在牛津大学举办的CHAR(10)会议中也有SE-PostgreSQL的专题演讲。 本文主要介绍数据库部分, PostgreSQL与SELinux的安全策略一致性设计方案和简单范例。 何为SE-PostgreSQL? Security-Enhanced PostgreSQL(简写SE-PostgreSQL) 是一个PostgreSQL内建的安全扩展。与SElinux一起提供自操作系统到数据库系统一致的精细化强制访问控制特性。 为何需要SE-PostgreSQL? 未使用强安全控制的RDBMS进程间通信实例图: SELinux 是操作系统特性,用于在被操作系统管理的所有文件上实施安全策略,包括文件,sockets,内部进程通信对象等等。保护机密信息不被泄露是SELinux的最重要的目标。尽管如此,如果信息通道没有相应的策略的话,信息泄露可能出现在信息通道环节。所见通常会说,整个系统的安全级别决定于最脆弱的信息交换通道。所以要确保整个系统的安全,必须建立系统一致性的安全策略就像SELinux所做的一样。 通常情况下,私有信息的隔离是在用户级别来隔离的。但是不得不考虑到的是内部进程通信,这些对于SELinux来说是不可见的。 为了避免这种不受控制的信息泄露,必须将SELinux的策略做到更加底层。比如RDBMS系统就是所谓的不受SELinux控制的底层。 SE-PostgreSQL可以利用SELinux特性控制这些不被SELinux控制的系统资源,就好象被操作系统使用SELinux管理一样。从而使整个系统的安全策略一致。 统一的信息流控制实例: 左边是传统的PostgreSQL,右边是SE-PostgreSQL. 在传统的PostgreSQL系统(并且操作系统使用了SELinux策略)中: 在系统级用户层面,当他往文件系统写数据的时候,数据被打上了安全标签。当底层用户需要访问这个在文件系统上的数据时,违反策略的话将不被允许访问。 在系统级用户层面,当他往数据库插入一条记录时,PostgreSQL不记录安全标签信息,所以的话底层用户可以有权限访问到这些记录。 在SE-PostgreSQL(并且操作系统使用了SELinux策略)中: 写入文件系统的情况与传统的PostgreSQL结果一致。 写入数据库时,记录将被打上安全标记,所以底层用户没有权限的情况下将不能访问到在SE-PostgreSQL中的资源。 因此在SE-PostgreSQL中,在整个数据流控制过程中使用了系统级一致的访问控制策略。 强访问控制(MAC): 传统的PostgreSQL有一致超级用户,类似操作系统的ROOT,可以访问,修改,删除任意数据库对象。 SE-PostgreSQL提供强访问控制特性,应用在所有的数据库客户端和所有用户上。 当MAC或数据库原有的GRANT/REVOKE控制的访问权限不能满足时,将无法访问到被访问的资源。 精细化访问控制(fine-grained access control): SE-PostgreSQL提供比传统PostgreSQL更加强大的精细化访问控制功能,包括列访问控制和行访问控制。 如图: 图上这张表一共包含6行记录,其中4行标记为unclassified,2行标记为secret,这种类似于SELinux的安全标签存储在表的系统列security_context上。当高层用户访问时可以看到6行,但是底层用户访问是带secret的两行将被忽略。 列级别访问控制,当用户访问不被授权的列时,访问被拒绝。 SE-PostgreSQL使用范例: 1. 行级访问控制 使用下列SQL在SystemLow-SystemHigh,unconfiged_t域创建范例表,函数。 CREATE TABLE genre ( gid     integer primary key, dsc     varchar (32) ); GRANT ALL ON genre TO PUBLIC; CREATE TABLE drink ( id      integer primary key, gid     integer references genre(gid), name    varchar(32), price   integer ); GRANT ALL ON drink TO PUBLIC; INSERT INTO genre (gid, [...]
19:43 恩墨科技备份恢复培训课程顺利结束 (3207 Bytes) » Oracle Life

作者:eygle 发布在 eygle.com

昨天,恩墨科技为期四天的备份恢复课程顺利结束,这是我们第一次开设备份恢复的课程,课程内容完全由恩墨科技定制而来,在培训过程中,收到了学员们的认同与好评,这样的定制课程我们将继续拓展下去。

目前,恩墨科技定制好的课程包括:性能优化、诊断案例、备份恢复、RAC集群等。
这些课程在未来都将按照大家的参与度,以周末班或者脱产班等方式开展。

为了加深学习和理解,我正在考虑将系列课程分解为2天的单元课程,然后以周末班的形式将授课周期拉长到一个月甚至数月,以加强大家的理解和消化,更可以进行学习后的培训答疑等等交互。

我们希望能够做出一点与众不同的培训课程。

感谢支持和参与这次培训的朋友门!

ACOUG活动

照例,我们出版了一份"恩墨科技"独家的证书,作为培训纪念:

Cert2.jpg我们将继续努力!



相关文章|Related Articles

评论数量(4)|Add Comments

本文网址:

2010-06-05 Sat

22:29 伪递归 (2522 Bytes) » DBA@SKY-MOBI
一个过程/函数/方法直接或间接调用自身的算法称为递归,在程序设计中使用很广泛,减少了程序代码量,使程序简单易懂,但是在实际运行中,其效率相对要慢一些,而且栈空间的使用也会造成一些问题 一般来讲,如果算法是可以递推的,则可以直接使用迭代进行处理,如果递归树中存在大量重复运算,则可以改为动态规划,这里讨论更通用的办法,用栈模拟来实现伪递归,理论上讲,所有的递归都可以通过栈模拟修改为伪递归,所以这里也借用了一些可以迭代的算法作为例子,另外,只讨论直接递归,间接递归的修改因为过于复杂而且实用性不高,不予考虑 首先要搞清楚递归的原理,简单地讲,一个函数调用另一个函数的时候,会将当前环境压栈,从函数返回时,会从栈中恢复调用时的环境,因此,我们只要做一个模拟栈来保存环境,并且修改调用和返回的方法即可 其次需要说明的一点是,这个办法并不会降低算法复杂度,和算法方面的改进比起来,就好比战术和战略的区别,因此很少在算法书中看到这类介绍,但是在实际开发中,这个办法的确可以解决一些问题,另外,几乎所有讲C的书都对goto深恶痛绝,但是为了使伪递归程序看起来清晰,我觉得还是goto最好,对于不支持goto的语言,写起来稍微有点麻烦 1 需要构建一个栈 2 每次递归调用的时候,将当前环境压入栈,然后更新环境,goto至函数开头 3 return的时候,如果栈空,则return,否则从栈中弹出之前的环境,并goto至递归调用结束的地方 上述3步是通用方式,实际情况要复杂一些 看一个简单的递归阶乘程序,几乎所有的递归教程都会拿它做例子 unsigned int f(unsigned int n) {     unsigned int t, r;     if (n <= 1)     {         return 1;     }     t = f(n – 1);     r = t * n;     return r; } 实际上写成return n <= 1 ? 1 : n * f(n – 1)会更简洁,但是为了分析和修改,拆成上面这样更好一点 当然这个算法可以直接用迭代,但是这里我们作为一个例子,按照上面3步实现其伪递归程序,其中关于栈的所有操作都进行了封装,没有具体展开: unsigned int f(unsigned int n) {     Stack stk;     unsigned r; recursion:     if (n <= 1)     [...]