Oracle DBA|MySQL DBA|数据库管理,架构,监控与性能优化 --- NinGoo.net

NoSQL,关系数据库终结者?

作为一个DBA,几年走过来,工作中历经MS SQL Server 2000/2005,Oracle9i/10g/11g,MySQL5.0/5.1等不同的数据库产品和版本,对于关系型数据库系统(RDBMS)应该说有了一定的了解。从一个数据库切换到另外一个数据库,虽然有些许艰难,却谈不上抗拒,甚至乐意主动去深入了解其他的数据库产品。关系理论的成熟,造就了这三十年来关系数据库在数据领域的绝对地位。

这两年在互联网行业,时间虽然不长,却深切的感受到了一个大型网站真实的压力。随着业务滚雪球式的增长,关系数据库由于对数据一致性的强硬要求(ACID),在扩展性方面天生不足,可以预见的天花板犹如达摩克利斯之剑,随时可能落下。SQL优化,应用重构,硬件升级,垂直拆分,能用的武器轮番上场,也不过救急于一时。要能做到系统随着网站压力几乎无限制的扩展需求,水平拆分横向扩展是不可避免的终极魔法。过去一年,我们也在一些应用上逐步尝试水平拆分,遇到过各种各样的问题,当然也有很大的收获,积累了很多的经验。MySQL作为开源的关系数据库,也开始得到大规模的应用,毕竟水平拆分后数据库的规模将是指数级的增长,商业数据库如Oracle的成本,是不得不考虑的一个问题。

我们所遇到的问题,相信所有大型的互联网站都会碰到。关系数据库有其不可替代的特性,但是,我们真的所有的数据都需要使用关系数据库么?或许一个简单但是更加容易扩展的key-value存储更能够满足很多互联网应用的数据存储需求,Google和Amazon相继推出BigTableDynamo,可以说是在分布式数据库方面一个开荒式的尝试。2009年初,一个叫做NoSQL的组织开始出现并运作,纠集了一支优秀的开源部队想要革了关系型数据库的命,至少是想革了关系型数据库在互联网行业的命。不管NoSQL是不是关系型数据库的终结者,却确确实实在推广一些优秀的开源分布式数据库产品,作为DBA,或许我们是时候花点时间去了解一下这个对手了,不然饭碗丢了可能还不明白是谁抢去了,呵呵。

下面是wikipedia上列出了NoSQL的一些开源项目,有时间应该去了解一下。实际上,淘宝也有在开发并使用自己的一套分布式cache和持久化系统,不知道什么时候也能看到开源版本的出现,呵呵。
* Cassandra
* Chordless
* CouchDB
* Db4o
* GT.M
* Hbase
* Hypertable
* Memcachedb
* Mnesia
* MongoDB
* Neo4j
* Project Voldemort
* Redis

发现有半个月没写blog了,这篇比较水,充一下数。

如何在AIX中编译Perl

AIX默认是不带编译器的,所以如果要自己编译Perl,需要先安装编译器。开源的gcc自然可以算是最佳选择。

在64位平台的AIX中,如果选择使用gcc来编译perl源代码,默认情况下是编译成32位的版本。这样在编译DBD::Oracle的时候也需要选择正确的32位库,否则无法编译成功。也可以选择将Perl编译成64位的,这样在64位平台上应该更方便些,很多依赖库的路径使用默认即可。

编译成32位Perl

$./Configure -des -Dprefix=/opt/perl  -Dcc=gcc
$make && make install

编译成64位Perl

$./Configure -des -Dprefix=/opt/perl  -Dcc='gcc -maix64'
$make && make install

注:gcc在linux下64位编译选项为-m64,在HP-UX下64位编译选项为-mlp64。不同平台下需要编译64位程序,选用不同的选项即可。为了确认编译后的版本,可以使用-V选项运行perl:

$./perl -V
Summary of my perl5 (revision 5 version 10 subversion 1) configuration:

  Platform:
    osname=aix, osvers=5.3.0.0, archname=aix-64all
    uname='aix dbtest 3 5 00cad8cf4c00 '
    config_args='-des -Dprefix=/opt/perl -Dcc=gcc -maix64'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=undef, usemultiplicity=undef
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='gcc -maix64 -maix64', ccflags ='-D_ALL_SOURCE -D_ANSI_C_SOURCE
-D_POSIX_SOURCE -DUSE_NATIVE_DLOPEN -fno-strict-aliasing -pipe
-maix64 -DUSE_64_BIT_ALL',
    optimize='-O',
    cppflags='-D_ALL_SOURCE -D_ANSI_C_SOURCE -D_POSIX_SOURCE
-DUSE_NATIVE_DLOPEN -fno-strict-aliasing -pipe'
    ccversion='', gccversion='4.2.0', gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=87654321
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=8
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='gcc -maix64 -maix64', ldflags =' -Wl,-brtl -Wl,-bdynamic -Wl,-b64'
    libpth=/lib /usr/lib /usr/ccs/lib
    libs=-lbind -lnsl -ldbm -ldl -lld -lm -lcrypt -lc
    perllibs=-lbind -lnsl -ldl -lld -lm -lcrypt -lc
    libc=/lib/libc.a, so=a, useshrplib=false, libperl=libperl.a
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_aix.xs, dlext=so, d_dlsymun=undef,
ccdlflags='-Xlinker -bE:/opt/perl/lib/5.10.1/aix-64all/CORE/perl.exp'
    cccdlflags=' ', lddlflags='  -Wl,-b64 -Wl,-bhalt:4 -Wl,
-G -Wl,-bI:$(PERL_INC)/perl.exp -Wl,
-bE:$(BASEEXT).exp -Wl,-bnoentry -lc -lm'

Characteristics of this binary (from libperl):
  Compile-time options: PERL_DONT_CREATE_GVSV PERL_MALLOC_WRAP USE_64_BIT_ALL
                        USE_64_BIT_INT USE_LARGE_FILES USE_PERLIO
  Built under aix
  Compiled at Dec  1 2009 19:48:22
  @INC:
    /opt/perl/lib/5.10.1/aix-64all
    /opt/perl/lib/5.10.1
    /opt/perl/lib/site_perl/5.10.1/aix-64all
    /opt/perl/lib/site_perl/5.10.1

如何让Perl脚本同时只运行一个实例

用Perl写了一些监控脚本,放在crontab中调度执行。有时候会发现一个脚本运行时间过长,会同时跑起多个实例,因此有必要为脚本加上控制,只运行一个实例运行。

最简单自然的想法,在脚本中检查并创建一个空的lock文件,脚本结束时再删除。通过判断文件是否存在的方式来判断脚本是否已经运行。不过这样做有个bug,如果脚本运行过程中异常终止,lock文件没有正常删除,就会导致脚本无法再运行。

空的lock文件不行,那么考虑在lock文件中加入一点内容,比如进程的PID号,然后通过检查该PID号的进程是否还在运行,就能避免上述bug了。在CPAN上有很多现成的模块能够完成上述功能,如File::LockfileFile::PidProc::PID::File 等。

下面是File::Lockfile的一个示例,非常简单:

#!/usr/bin/perl -w
use File::Lockfile;
# lock文件位于/tmp目录,名为test_file_lock.lck
my $lockfile = File::Lockfile->new('test_file_lock','/tmp');
# 检查脚本是否已经运行,如已运行则退出
if ( my $pid = $lockfile->check ) {
  print "program is already running with PID: $pid";
  exit;
}
#更新lock文件
$lockfile->write;
# 脚本逻辑
sleep 30
#删除lock文件
$lockfile->remove;

通过查看File/Lockfile.pm的源代码可以看到,判断lock文件中记录的进程是否已经运行,简单的通过kill 0,$pid即可实现。所以即使不用上述模块,自己实现也是非常容易的。

Perl自定义模块的路径包含问题

Perl模块是重用代码的好方法,但是在调用自定义模块时的路径问题困扰了我许久。之前一直都是通过在代码中直接将自定义模块所在的绝对路径写入到@INC数组来解决的,以下示例,加入perl脚本放置在/opt/perl/bin,而自定义模块放在/opt/perl/lib目录:

BEGIN {
    push (@INC,'/opt/perl/lib');
}

或者

BEGIN {
    unshift @INC,'/opt/perl/lib';
}

或者

 use lib '/opt/perl/lib';

使用绝对路径比较麻烦,如果将程序迁移到另外的安装目录,就需要去更改所有的脚本。而直接在use lib中使用相对路径,如use lib ‘../lib’;,测试发现手动执行bin目录下的perl脚本是可以的,但是放到crontab里去跑就找不到模块了。于是想先找到bin目录的路径,然后通过相对路径跳转到lib目录,在《Perl Cookbook》终于找到了我想要的,使用FindBin模块就能实现梦想了:

use FindBin qw($Bin);
use lib "$Bin/../lib";


常用标签: oracle life MySQL Oracle11g blog dba 新特性 oow2009 oow wordpress

最新评论 | Recent comments