2009年12月28日星期一

Python study

python解释器启动:
python
退出 : Ctrl + d 或 exit() (2.5.2)
查看版本 : python -V

help() 进入帮助模式:
输入modules, keywords, topic可以查看
要看全的python帮助,要设置环境变量 PYTHONDOCS 如
$env PYTHONDOCS=/usr/share/doc/python

python程序的编写
文件头
#!/usr/bin/python

注释 : 用#

数据类型:
整型,长整型,浮点数,复数(-5+4j)
布尔型:True, False;注意大小写
字符串
  • 用'或", '与"是相同的,其中可以用转义字符\,如\' \n, 行末的\表示下行继续,而不是开始新行
  • 自然字串,表示不用转义,在字串前加r或R,如 r'Hello world \n',对于正则表达式,应采用自然字串.
  • Unicode字串,加前缀u或U.
  • 用'''或"""三引号可以表示多行字串,在三引号中可以自由使用'或", 也可以用转义,也可加前缀u,r, u必须在r前面
  • 字串不可变
  • 字串会自动级连 如 : 'hello' " world"会变成'hello world'
None表示没有值
没有char数据类型

变量名:第一个字符必须是字母表字母,大小写都可,或_,其它部分可以再加上数字,大小敏感,不能有空格, 对变量不需要声明数据类型
del a #删除变量a

对象 : 程序中的任何东西都是对象,包括数,字串,函数.
;可以用以分隔逻辑行,建议用一个物理行只含有一个逻辑行.

缩进是重要的,用来决定语句的分组,

特别的运算符:
x**y 返回x的y次幂
// 取整除
% 取模
<< 左移, >> 右移一比特
& 按位与
| 按位或
^ 按位异或
~按位取反
not 非
and 与
or 或

优先级:
lambda; or;and;not x;in, not in;is, is not; <, <=, >,>=,!=,==;|;^;&;<<,>>;+,-;*,/,%;+x,-x(正负号);
~x;**;x.attribute;x[index];x[index:index](寻址段);f(arguments ...);(experession,...);[express,...](列表显示);{key:datum, ...}(字典显示);'expression,...'

控制流
if的语法
if guess==number:
print 'Congratualtions'
elif guess < number:
print 'No, it is a little highter than that'
else:
print 'No, it is a little lower than that'

print 'Done'

使用while语句:

running = True;
while <条件>
[else:
]
注意while可以带else从句

for循环:
for i in range(1,5)
print i
else:
print "The for loop is over"
else部分是可选的,总是在for结束时执行一次,除非遇到break

break用于终止循环,这使得for,while的else块不执行
continue 用于跳过循环块中剩余的语句

函数:
def sayHello():
print 'Hello world'

sayHello() #调用

可以使用参数如
def printMax(a,b)
if a>b:
print a, 'is maximum'
else:
print b, 'is maximum'

对数值或数值型变量采用值传递.

在函数中可以定义局部量也可以定义全局量,这样可以为函数外的变量赋值

def func():
global x

print 'x is', x
x = 2
print 'change local x to ', x

x = 50
func()
print 'value of is', x

同C++一样,形参表末尾的参数,可以有默认参数

键参数,如
def func(a, b=5, c=10):
print 'a is',a,'and b is',b,'and c is',c

func(3,7)
func(25,c=24)
func(c=50,a=100) #指定键参数a, c

return用来返回,也可以返回一个值

pass表示一个空的语句块

DocStrings
来自函数的第一个逻辑行的字串. help 也只是取到了函数的__doc__属性
如:
print int.__doc__
print 'hello'.__doc__

模块:
使用sys模块 :
import sys

sys.argv字串列表,指的是命令行参数列表
sys.argv[0]指是程序(python文件)名,1以后是参数

如果使用from sys import argv 可以每次用argv时避免打sys. 也可以
from sys import *
from mymodule import sayhi, version #import 了两个成员

模块的__name__
如:
#!/usr/bin/python
# Filename: using_name.py

if __name__ == '__main__': #表示python程序被单独运行
print 'This program is being run by itself'
else: #表示被调用
print 'I am being imported from another module'

用dir来查看模块属性
import sys
dir(sys)

dir() # 得到当前模块的属性

列表 list, 是一个类,
['apple','orange','banana']
可以改变,增删,排序,从0开始索引

元组 tuple
不可改变值,如同字串
('apple','orange','banana')

list和tuple都可以嵌套,且不会改变身分

使用tuple输出

age = 22
name = 'Swaroop'

print '%s is %d year old' %(name,age)
print 'name is %s'%name #只有一个参数时name

字典dict
d={key1:value1, key2=value2}
key是无顺序的
d[key1]来索引

索引 : 用[]
slice :
d[1:3]从第一个元素一直取到第三个,实际是返回第1,2个,
d[1:-1]从第一个直到倒数第一个,不包括倒数第一个
d[2:] 从第2个到结尾
d[:]全部

对象赋值是引用
shoplist = ['apple', 'mango', 'carrot', 'banana']
mylist = shoplist #mylist 是shoplist的一个引用.

复制:
mylist = shoplist[:] #生成shoplist的一个复制

字符串的方法:
name = 'Swaroop'
if name.startwith('Swa') : #startwith 返回布尔值
print 'Yes, the string start with "Swa"'

if 'a' in name : # in 某个子串是否存在
print 'Yes, it contains the string "a"'

if name.find('war') != -1 : # 查看某子串的位置, -1表示没有
print 'Yes, it contains the string "war"'

delimiter = '_*_'
mylist = [ 'Brazil', 'Russia', 'India', 'China' ]
print delimiter.join(mylist) #用分隔符将字串list连接起来

''.join(alist) #直接连接list或tuple,没有分隔符

定义类:
class Person :
'''Represents an person'''
population = 0 #相当于静态量
def __init__(self, name): #定义初始化函数,注意必须有self
self.name = name #相当于普通成员变量
population += 1

def sayHi(self) :
print 'Hello, my name is', self.name
def __del__ (self): #相当于析构函数
population -= 1
p = Person('Hzt')
p.sayHi()

继承
class SchoolMember:
'''Represents any scool member. '''
def __init__(self, name, age):
self.name = name
self.age = age
...
def tell(self) :
...

class Teacher(SchoolMember) :
'''Represents a teacher'''
def __init__(self, name, age,salary):
SchoolMember.__init__(self, name, age)
self.salary = salary
...

def tell(self):
...

class Student(SchoolMember):
'''Represents a student'''
def __init__(self, name, age, marks):
SchoolMember.__init__(self,name,age)
self.marks = marks
...

def tell(self):
...


有关print的一些技巧:
print line, #输出一行内容并避免自动的换行符
print #输出一个换行符

储存与读取(序列化及反序列化)
#!/usr/bin/python

import cPickle as p # cPickle速度更快; 用import ... as 可以使用更短的模块名
#import pickle as p

shoplist = 'shoplist.data'

shoplist = [ 'apple', 'mango', 'carrot' ]
f = file(shoplistfile, 'w') #创建一个可写入的文件
p.dump(shoplist, f) #用pickle写入一个对象

del shoplist #删除shoplist对象

f = file(shoplistfile)
storedlist = p.load(f) #读出这个list对象
print storedlist

错误和异常:
try: #开始捕捉错误
s = raw_input('Enter something -->')
except EOFError: #如果错误是EOFError
print '\nWhy did you do an EOF on me?'
sys.exit()
except: #其它的错误
print '\nSome error/Exception occurred.'

print 'Done'

还可以加上else块,如果没有异常, else从句会执行

如何引发异常
class ShortInputException(Exception):
'''A user-defined exception class.'''
def __init__(self, length, atleast):
Exception.__init__(self)
self.length = length
self.atleast = atleast

try: #开始捕捉错误
s = raw_input('Enter something -->')
if len(s) <3:
raise ShortInputException(len(s), 3)#抛出异常

except EOFError: #如果错误是EOFError
print '\nWhy did you do an EOF on me?'
except ShortInputException, x: #如果错误是ShortInputException, 用x来引用
print 'ShortInputException: The input was of length %d, \
was expecting at %d' % (x.length, x.atleast)
else: #else从句
print 'No exception was raised'

以下的块不能与try ... except合用,只能嵌套使用
try:
...
finally:
...

特殊方法:
__init__(self, ...) #初始化方法
__del__(self) #析构方法
__str__(self) #使用print语句或对对象调用str()时
__lt__(self,other) #当使用小于(<)时,对+, >都有特殊方法
__getitem__(self, key) #使用x[key]索引时调用
__len__(self) #对序列对象使用内建的len()函数时调用

在函数中接收元组或字典,用*或**前缀如
def powersum(power, *args)
total = 0
for i in args:
total += pow(i,power)
return total

如果使用**作前缀,所有多余的函数参数会被认为是一个字典的键/值对.

exec 'print "Hello world"' #执行一个python语句

eval('2*3') #计算一个字串中有效Python表达式.







2009年12月27日星期日

Ganglia 3.1.2 源码

gmond :

主要有4个文件:
cmdline.h
cmdline.c
ganglia.h
gmetric.c

main :
  1. Parse 命令行到全局量args_info,类型是结构体 struct gengetopt_args_info(cmdline.h)
  2. 创建全局量global_context,类型是struct Ganglia_pool*. 实际类型是apr_pool_t*(apache的内存池). struct Ganglia_pool根本未定义.
  3. 通过分析配置文件,创建全局量gmond_config,类型是struct Ganglia_gmond_config* (未定义类型),实际类型是cfg_t(confuse.h, 是一个section,section可以嵌套,还包含一个选项(字符,数据,布尔,其它的section)的列表.
  4. 创建全局量send_channels (UDP发送通道),类型是struct Ganglia_udp_send_channels*,实际是apr_array_header_t*.这个send_channels的数组对应到每一个配置文件中的udp_send_channel.
  5. 创建全局量gmetric,仅分配空间, 类型struct Ganglia_metric* , struct Ganglia_metric中有Ganglia_pool,struct Ganglia_metadata_message* 和char* 的value及void* 的extra. Ganglia_metadata_message表明了一个metric的类型,名称,计量单位,slope(斜率),tmax(在两个gmetric call之间最大秒数,默认60)和dmax(这个gmetric最大生命周期,默认0)
  6. 然后判断一下命令行参数是否有spoof及heartbeat如果都有,设置gmetric为heartbeat;否则设置metric的各项参数(name,value,type,unit, slope, tmax, dmax)
  7. 如果有spoof或heartbeat,将它们加入metric的extra子域中(apr_table_t)
  8. 然后将metric通过send_channels发送出去( Ganglia_metric_send() 来自libgmond.c),先发 metadata,再发value
  9. 清理

2009年12月16日星期三

Ganglia & Nagios



ganglia.info


术语:
XDR : eXternal Data Representation.外部数据表示法.独立于机器架构,在异种机器间传送数据.XDR定义了如下数据类型: boolean, char(8bits),int(32bits),hyper(64bits),float,double,quadruple,enumeration, structure,string,fixed length array, variable length array, union, opaque data, optional data(类似C指针,但还有一个"存在与否"的标记), 参考RFC 1014, RFC 1832, RFC 4506

分成如下模块:

监控:
gmond : ganglia monitoring daemon, 是一个轻量的服务.在每台你希望监控的机器上安装.采用简单的监听/发布协议,通过XDR收集监控状态并 通过TCP上的XML来共享这些信息.gmond是可移植的,收集几十种系统数据,如CPU,内存,磁盘,网络,进程数据.

gmetad : ganglia meta daemon,一个服务从其它的gmetad和gmond来源存贮它们的状态到磁盘中多个索引过的round-robin数据库.gmetad提供了简单的查询机制来收集特定的一组机器的信息.gmetad支持层次化的委托方式来建立可管理的监控域.

gmetric : ganglia metric tool是一人命令行工具,你可以用来加入定制的检测值到ganglia的主机.可以用来伪造gmond信息,使它看起来象一个不同的主机.

gstat : ganglia stat tool是一个命令行工具来直接查询gmond的检测值

web : ganglia web frontend 图形化的web介面展现保存在gmetad上的检测数据,用PHP写的.

执行:
Ganglia 执行环境:
GEXEC是一个可扩展的集群远程执行工具.提供了快速,RSA鉴权的并行的分布工作.提供了透明的标准输入输出,出错和信号.提供了本地环境的复制.能够健壮的扩展到系统到几千个节点
可以利用authd (from RocketCalc)来获得更好的性能和易维护性.

还有embedded metrics, 用这个可以发送gmetric兼容的数据包,支持了多种语言,如C++, python, perl...



Hadoop有集成的钩子在ganglia上
http://wiki.apache.org/hadoop/GangliaMetrics
可以在Hadoop配置文件中配置,向指定的ganglia服务器发送数据.这个实现些已经在Hadoop的代码中(hadoop-core)了.实现是直接用UDP发数据包到ganglia服务器,还是比较简单的.

jmxetric
集成JMX,将MBean属性报告到Ganglia.
http://code.google.com/p/jmxetric


Nagios主要功能:
  • 监控网络服务(SMTP,POP3,HTTP,NNTP,PING...)
  • 监控主机资源(CPU,磁盘使用...)
  • 简单插件设计可以让用户容易开发他们的服务检查
  • 并行的服务检查
  • 可以定义网络主机层次结构,可以检测和区分下线的主机和不可达的主机
  • 在服务或主机发生问题和解决时,通过email,呼机,或用户定义的方法来发送通知
  • 自动log文件轮替
  • 支持实现冗余监控主机
  • 可选的Web接口.
查看ganglia的内容,可以telnet到主机(gmond)的tcp端口(默认8649)来读取


Nagios相对功能比较完整:
开源source forge
有通知功能
多用户,多角色的dashboard和控制接口
超过200社区提供了插件, 如下两大类
  • 输入源
  • 通知机制
扩展到监控超过100000节点
支持ganglia作为输入源

集成nagios时,注意将节点的cfg文件(在/usr/local/nagios/etc/及子目录中)中,定义host 名字的时候与ganglia汇报的相一致

define host {
use desktop-server
host_name NJ-ZHENTAOHUANG.WORKGROUP
address NJ-ZHENTAOHUANG.WORKGROUP
}

从ganglia中TCP端口中读到的是:
NAME="NJ-HZT-VM2.WORKGROUP" IP="10.64.38.211" REPORTED="1262598648" TN="9" TMAX="20" DMAX="0" LOCATION="n ...





2009年12月1日星期二

MySQL插件式存储引擎



插件式存储引擎本身是数据库服务器的组件,负责对执行真正的数据IO操作,也使得并强制一定的功能集为特定的应用服务.

插入引擎的方法:
mysql> INSTALL PLUGIN ha_example SONAME 'ha_example.so';
拔出引擎的方法:
mysql> UNINSTALL PLUGIN ha_example;


在存储引擎中一些支持底层结构的组件的是什么?一些关键功能如下:
并发 : 锁粒度的要求.以及多版本并发控制和快照读的功能
事务支持: 遵从ACID原则
引用完整性:使服务器强制关系型数据库通过DDL定义的外键保证引用完整
物理存贮:存贮数据到磁盘
索引支持:不同的应用场景总是从不同的索引策略中受益,每个存贮引擎总有它自己的索引方式,虽然一些如B树索引总是对所有引擎通用的.
内存缓冲:采用内存缓冲能取得更好的响应时间
性能辅助:包括多IO的线程来并行操作.线程并发,数据库检查点,大批量插入处理
其它目标的特性:如地理空间操作,安全限制等等

源码:
自定义存贮引擎要实现handler接口,这个是在sql/handler.h.可以参考的例子在storage/下
可参考的实现如 : csv (272k), MyISAM (1.5M), Innobase(5.5M)(InnoDB), Innodb_plugin(6.7M)

handler类主要提供了创建,删除表,写,更新,删除行,索引,更新,Scan,锁的虚函数.子类重载它来实现一个数据存贮引擎.





2009年11月29日星期日

GreenPlum





基于PostgreSQL大型并行处理(Massively parallel processing, MPP, 即share-nothing architecture)数据库


Greenplum DB 布署图

Master : 主机
Greenplum DB的入口, 安装有PostgreSQL 8.2.10,使客户端可以用psql连接连入或用API如JDBC,ODBC. 存放global system catalog.(系统表的集合,包含有Greenplum DB的元数据.但不包括用户数据.

Segment : 段
用于存放数据(用户自定义表和索引)和处理查询的主要地方. Segment实例是数据库服务器进程.推荐用一个有效的CPU或CPU核来服务一个Segment.

Interconnect : 互联
Greenplum DB的网络层面.采用标准的标准的千兆以太网.默认使用UDP,如使用TCP会有1000个段的限制

Greenplum DB可选的支持冗余和故障恢复,无SPOF.有如下保障措施
1) 段监控:
可设置镜像段,,可以用镜像段在主段失效的时候恢复.条件是要有足够的机器
在镜像打开的时候,系统会自动故障恢复,当Master连接一个段失败,它会标记这个段是不可用的直到这个段重新上线,Master会重标记它为可用.
故障恢复要求系统配置成fault operational mode.在只读模式下,DDL,DML命令瘵不能执行.而continue mode,每个数据块只要有有一个段实例在运行,系统会连续运行,一旦有一个失败,系统必须关闭来恢复失效的段. 如果镜像没有打开.

2) 主机监控:
可以布署主机实例的镜像或备份.备份主机采用warm standby(热备)方式.备份主机通过复制transaction log的方法同步.

3) 冗余的互联:
双千兆交换机,和冗余的连线.

并行数据装载:
外部表装载.如果采用Greenplum DB并行文件服务器(gpfdist),可以达到装载效率2T/小时


Greenplum如何存贮数据:
采用star schema的一个例子, factor table是sale, dimension table是customer, vendor, product.
如上图所示,sale, customer, product, vendor分别是不同的表.

GreenplumDB的分布策略:
1) Hash分布 : 这是默认的,一个或多个表的列的值做为分布键(distribution key),这个分布的Key用来hash每一行到一个特定段.相同的键值,总是被Hash到同一个段.如果没有定义,一般以主键或第一个列作为分布键
2)随机分布:用round-robin方式分布每行记录.这种性能不如Hash分布好

查询处理:
当Greenplum从前端接收到SQL语句,主机会分析这个查询,并做优化,创建并发查询计划(parallel query plan),主机分发这个计划给所有的segment来执行.每个Segment执行本地数据库操作来响应.
除了典型的数据库操作(扫描,联接)GreenplumDB还有附加的操作类型称为motion,一个motion操作有在段之间移动数据元组的动作.
GreenplumDB将工作从查询计划切分为slices.一个分片是能在段的层次上独立完成的一部分工作(不单是一个工作项,而有可能是多个工作项).当一个motion发生时,在参与段的两端各有一个slice.

GreenplumDB创建一批量的进程来处理查询的工作.在主机上查询的工作进程称为query dispatcher (QD), QD负责创建分发查询计划,并汇总和展现最终结果.在段上,一个查询工作进程称为query executor(QE). QE负责完成工作的片断.每个slice都有被指派到一个工作进程上. 每个段都有一定量的进程进行并发的服务.相关的工作于同一slice查询的进程被称为gang.



MapReduce:

允许开发者写Map和Reduce用多种的脚本语言,如Python和Perl.GreenPlum的MapReduce提供开发者访问数据的弹性,可以在文件中,可以在网站上,甚至是任意的操作系统命令.Greenplum提供这些数据相对于传统数据库而言无额外的开销:无锁,日志,分布提交协议.在另一方面,对必须要由RDBMS全功能保护的数据,Greenplum MapReduce 提供了有效的原生方法访问数据记录.它会把MapReduce程序推向Greenplum并行的数据库引擎上,来获取数据.

MapReduce的特性:
1) 由于GreenplumDB表分布在多台机器上,初始的Map阶段运行在数据分区所在的数据引擎上.
2) Greenplum扩展表机制允许文件和数据生成程序被注册为只读表,然后通过SQL语句来查询.
3) Greenplum能存贮MapReduce的结果到一个文件系统,但能同样方便的保存到GreenplumDB,并且有全的ACID支持及可选的子查询通过BI工具分析这些输出.产生结果也是并发的
4) Greenplum MapReduce framework能使用任意的SQL查询作为输入.另一方面,Greenplum MapReduce脚本能被注册成数据库中的视图(view)来作为查询中的虚拟表.

报价:
Perpetual license : $ 16K / core, 或者说 $70K/terabyte. 年维护费22%维护价. 或50%永久许可证下年订阅费. 可以再商量

2009年11月26日星期四

Infobright



ICE (InfoBright Community Edition)
Features:
  • Data : SQL-92,加SQL-99的扩展,对视图和存贮过程的全支持
  • 灵活的模式支持
  • 业界标准的接口 : ODBC,JDBC,及原生的连接方式
  • API : C/C++,C#, Java(及原生的java驱动实现),Perl, PHP,Python,Ruby...
  • 并发的用户: 500个用户,32个并发查询
  • 操作系统: WindowsXP(32-bits), RHEL5(64b), Debian(64b), CentOS5(64b), Fedora9(32b), Ubuntu8.04(32b)
  • 处理器:AMD 和Intel x86, 推荐16G RAM
  • 高性能的数据装载器:一个定制装载器,跨多表的并发处理

好处:
  • 小的数据尺寸: ICE的压缩率为10:1
  • 高的扩展能力: 到50TB,(压缩后5T)单个服务器
  • Column-Based
  • 采用现成的硬件
  • 简单的管理: 利用MySQL的管理工具,并包括在ICE中了.
  • 低维护:自动管理知识节点
  • 装载即运行(Load and Go) : 用你现有的Schema不要物理视图,数据分区和索引的实现.
  • 支持装载格式: 可以装载文本文件
  • BI灵活:与MySQL集成,可以通过它受BI工具的支持,如Cognos, Business Object, SAS, Pentaho, JasperSoft, MicroStrategy.
IB的Architectrue的好处:
  • 理想的数据卷大小到30TB
  • 市场上领先的数据压缩技术(10:1到超过40:1),极大的减小了IO及存贮
  • 无许可证费
  • 对复杂分析查询的响应
  • 查询和装载时间在DB增长时保持不变
  • 不需要特别的Schema
  • 不需要物理视图,分区策略,或索引
  • 简单的建立和管理
  • 减少DW(data warehouse的成本)通过减少服务器的数量,还有总控的花费
  • 运行在低成本的现成的硬件上
  • 兼容BI工具 : Actuate, ...

IB的Architecture

  • Column Orientation
  • Data packs和Data pack 节点
三个层面:
Data Packs : 一个列中65536个项目被组在一起称为Data Packs. Data Packs改善了压缩率,因为可以根据数据类型提供压缩算法
Data Pack Node(DPNs) : 包含一个静态统计信息针对一个DP,DPN总是存在,这区别于传统数据库的索引
Knownledge Node (知识节点),是一个元数据集有关于DP或列之间的关系. 描述值的发生范围,也可描述与其它DB中数据的关系. 用于复杂的多表查询,如表联接,子查询(sub-queries)大多数都是在装载时创建,也有在响应时创建来优化性能.

  • 知识节点和知识网格
DPN与KN组了Knowledge Grid. 与索引不同的是它们不是手工产生的,而是自动生成,从根本上说,它们建立了DB高层次的视图
    • 优化器


    如何不用索引进行复杂的分析查询
    1) 利用DPNs(一些统计信息),如对于整型的列数据来说,一个DP有64k个数据项,对应的DPN就记录了这些数据项的最大值,最小值,及总和.有了这些数据在查询中,如果用对这列比大小的条件查询就可以区分出三类的DP
    i) 相关的DP, DP内的数据全部落在条件以内,(因此要对这个DP解压缩数据)
    ii)不相关的DP, DP内的数据全部落在条件以外(,因此可以忽略这个DP)
    iii)不确定的DP, DP内的数据部分落在条件以内(,因此要对这个DP解压缩)
    分析出三类DP后可以对特定的DP解压缩再分检其中的数据


    DPN可以针对不同数据类型,提供一些扩展的统计信息,如对于字母数字的数据类型,提供特定的字符在特定的位置出现的次数.
    左边是一个DPN的例子,说明一个表T有两列A,B,共有64k * 5条以内的记录
    也就是对于A,B各有5个DP及对应的DPN.对于DP A1(A列的第一个Pack, 共64k记录),DPN中记下它其中的最小值是0,最大值是5,总合(SUM)是10000.

    KN的例子是如有如下查询
    SELECT MAX(X.D) FROM T JOIN X ON T.B = X.C WHERE T.A > 6;

    其中T即上述的T表, X是另一个表,有两个整型列C,D,共64k*3以内的记录,也就是说有DP C1~C3, D1~D3.
    对其中条件T.B=X.C,可以利用DPN生成如下结果,称为KN


    这说明了一个关系,T.B和X.C有相等可能两个DP之间是标的1,否则是0.这是通过比较DPN中最大值最小值得出的结论.

    • 数据压缩
    用了空值Mask,(估计)有一个8k的位图,来表示某个DP中的值是空的.InfoBrigth有一套数据类型对应的压缩算法(专利申请中)

    InfoBright如何利用MySQL
    InfoBright实现了MySQL中的数据存贮引擎,如(MyISAM,InnoDB)等.



    InfoBright采用的是Rough Set Mathematics做为基础
    2000年时一个波兰数学家的团队开始改进Rough Set理论,研究出一个既有精度又有概算的灵活性的混合方法.他们总结了以上的思想 产生出一个新数据库引擎,2005开了InfoBright公司.



    2009年11月25日星期三

    InfiniDB


    Column-Oriented DBMS:
    如:
    EmpIdLastnameFirstnameSalary
    1SmithJoe40000
    2JonesMary50000
    3JohnsonCathy44000

    在row-oriented database中存储时被序列化成
    1,Smith,Joe,40000;2,Jones,Mary,50000;3,Johnson,Cathy,44000;
    在column-oriented DB中被序列化成:
    1,2,3;Smith,Jones,Johnson;Joe,Mary,Cathy;40000,50000,44000;

    区别在于:
    1) 适合于运算于行多列少(一个列的较小集合)数据表查询.
    2) 适合于更新整列的操作,可以不碰到其它列
    3) 而row-oriented DB适合于更新有单行的多列.当一行很小时,只要一次磁盘操作就可取回整行
    4) 而row-oriented DB适合于写入一个新行如果所有的列数据都提供的话

    InfiniDB 是属于Column-oriented DB,由Calpont Corp.提供, GPL v2许可证. Open source
    InfiniDB Features:
    • Column-oriented, 适合查询
    • 多线程设计.
    • 自动的水平和横向分区.即行列都能分区
    • 高并发:理论上无并发的限制,只受制于服务器的容量
    • 高速数据装载器
    • DML(可以视为是SQL的子集)支持 : 语句insert, update, delete
    • Transactional支持:
    • Crash恢复:
    • 多版本并发控制(MVCC),保证所有的语句执行在一个特定的snapshot中,系统称之为(System Change Number, SCN). 这个称为Version Buffer的东西由内存(表明一个被修改的8块的hash表)和磁盘结构(默认4 个1G的文件, 散布在一台机器的多个驱动器上,(就象InfiniDB的数据文件一样)组成.
    • 无需索引
    • 低维护需求,诸如不需要实例化的视图和统计表来达到高性能
    • Alter操作支持:add, drop
    • 逻辑数据压缩,透明的,当前只通过去除重复数据的方法来压缩.以后会有针对列级别上物理数据的压缩.
    • 性能自检:提供了SQL的分析和跟踪工具来查错和调优
    • MySQL作为前端接口
    • 运行在通用的硬件平台上
    • 无许可证费用
    • 商业智能(BI)工具兼容,因为用了MySQL的连接器,所有支持与MySQL兼容的BI工具
    From InfiniDB Technical Overview White Paper:
    对于有选择的查询,即只要求读取很少的列时,row-based DB要化5~10倍的物理IO相对于Column-based DB.
    因此Row-based DB利用索引,水平分区,物理视图,摘要表和并行处理来提高性能.这同时也带来了负面问题.如空间,索引的选择,更复杂的更新增删操作.

    Extract-Transform-Load (ETL)指数据处理的三个主要过程 : 从不同的来源抽取数据,变换及过滤数据(有时可能没有),装载数据到Data warehouse.
    通常reporting DB与data warehouse是不同的,它们仅是一个Transactional系统的镜像,用于查询当前或历史数据.数据在这两个系统间装缷,复制,或Extract-Load

    InfiniDB还有社区版和商业版之分,
    商业版还有如下Feature:
    • 大并行处理能力:能采用多台通用硬件平台的机器来达到性能线性增长.能动态加入节点
    • 分布式的Share-nothing数据缓冲: 有一个逻辑上的cache分布在各参于的节点中.要求大内存
    • 自动Failover
    • 自动并发的Scale-out
    • 自动软件打补丁管理
    Architecture:
    用户模块(User Module) ; 由小的MySQL实例和一些InfiniDB的掌控并发扩充的进程组成.本模块也负责将SQL查询分解在针对于"性能模块"的多个部分,最终本模块组装所有查询的结果给用户,可以有多个用户模块存在,这提供了高可用性配置及查询的负载平衡

    性能模块(Performance Module) : 负责保存, 读取, 管理数据库,处理块请求并传回"用户模块", 本模块从磁盘或Cache(也就是前述的Share-nothing的数据缓冲)中读数据.分布式Cache就存在于本模块中,增加PM也就增加了Cache. (好象只有企业版(商业版?)有)

    存贮(Storage)利用本地存贮或共享存贮(e.g. SAN (storage area network)), 可以是单台或多台服务器

    单台机(Community Edition) Architecture

    Enterprise (Commercial Edition) Architecture

    用户查询处理流程:
    1. 一个查询来到MySQL (InfiniDB Server), MySQL进行表操作从MySQL中得到一个查询执行计划
    2. InfiniDB转换MySQL表对象为InfiniDB对象,并发给一个UM
    3. UM转换MySQL执行计划并优化这些对象成为InfiniDB执行计划.UM决定这个计划的执行步骤和时机
    4. UM咨询Extent Map,来得到适合查询的数据的位置
    5. UM发送命令给PM,执行块IO操作
    6. PM进行预过滤,连接处理,初始化聚合数据和发回结果给UM
    7. UM进行最终结果聚合和合成最终结果
    8. UM返回结果集给用户
    InfiniDB的存贮思想:
    Block : 8k的数据块,有Logical Block ID,大小不能定制,但预读的数目可以定制
    Extent : 一个逻辑空间尺寸,存在于一个或多个的称为segment文件的物理文件中. extent大小受1)默认的行数2)一个列的数据类型, 如默认行数是8M,对一字节数据类型来说,Extent大小就是8M; 对于8字节数据类型来说,就是64M;对于可变长数据类型来说也是64M.当一个Extent满了,一个新的Extent就会被创建出来.
    Segment File : 当一个Segment文件达到它的Extent包含的最大数目,一个新的Segment文件就会被创建出来
    Partition : 与row-based DB不同之处在于它是一个逻辑上的对象.由一个或多个Segment文件组成. 一个列的partition数目是不限的.