Oracle MySQL NoSQL DBA|数据管理,架构,监控与性能优化 --- NinGoo.net
NinGoo's blog
  • 初略的翻了一下《1984》,直觉的浑身冷汗。 1 day ago
  • 其实更愿意坚持,有时候也是不得以。 @mujiang 1 day ago
  • 淘宝第一台小型机上的核心库的即将下线,完成了其五年的历史使命。接下来会有越来越多小型机存储的下线,pc化,水平化,可扩展高可用的趋势,不可阻挡。 2 days ago
  • 卓越的书,昨天就已经收到了。但是今天才收到卓越的邮件,说库房已经安排发货,预计明天可以送达,请您耐心等待、保持电话畅通并注意查收。这是什么系统啊,囧。 2 days ago
  • 昨天在卓越下单买的几本书上午就送到了,不到24小时,效率不错。 3 days ago

Cassandra运维之道

对于传统的关系数据库Oracle/MySQL等,NoSQL一个相当大的不足是文档资料的缺失。相对而言,Cassandra还能找到不少资料,这个ppt是我根据网上一些资料,结合这几天浏览了一点源代码的一些理解,整理的一个普及资料。名字起的有点大,可能有点地方理解有偏差,权当这是version 0.1吧,接下来一些产品会开始使用Cassandra,结合实际的运维经验,希望能逐步形成类似最佳实践的操作手册。

Cassandra之Token

有一个多月没有更新过blog了,有点惭愧。不管何种理由,不管工作生活有何种变动,有一些我们内心真正追求的东西,不能放弃。昨天晚上,世界杯大幕拉开,在等待揭幕战的过程中,看了一段Cassandra关于dht部分的源代码。要在生产系统中运维,则数据如何分布不得不做周详细致的考虑。

将Cassandra用于实际的生成环境,一个必须要考虑的关键问题是Token的选择。Token决定了每个节点存储的数据的分布范围,每个节点保存的数据的key在(前一个节点Token,本节点Token]的半开半闭区间内,所有的节点形成一个首尾相接的环,所以第一个节点保存的是大于最大Token小于等于最小Token之间的数据。

根据采用的分区策略的不同,Token的类型和设置原则也有所不同。 Cassandra (0.6版本)本身支持三种分区策略:

RandomPartitioner:随机分区是一种hash分区策略,使用的Token是大整数型(BigInteger),范围为0~2^127,因此极端情况下,一个采用随机分区策略的Cassandra集群的节点可以达到2^127+1个节点。嗯,为什么是2^127?因为Cassandra采用了MD5作为hash函数,其结果是128位的整数值(其中一位是符号位,Token取绝对值为结果)。采用随机分区策略的集群无法支持针对Key的范围查询。假如集群有N个节点,每个节点的hash空间采取平均分布的话,那么第i个节点的Token可以设置为:

 i * ( 2 ^ 127 / N )

下面的测试程序是从org.apache.cassandra.utils.FBUtilities类抽取出来的计算MD5值的函数,输入任何字符都可以得到其对应的MD5的整数值,利用该值和节点的Token对比即可知道该Key对应的数据归属于哪个节点:

import java.io.*;
import java.util.*;
import java.math.BigInteger;
import java.security.MessageDigest;

class get_md5{
  static final Scanner cin=new Scanner(System.in);

  public static byte[] hash(String type, byte[]... data){
    byte[] result = null;
    try{
      MessageDigest messageDigest = MessageDigest.getInstance(type);
      for(byte[] block : data)
        messageDigest.update(block);
      result = messageDigest.digest();
    }
    catch (Exception e){
      throw new RuntimeException(e);
    }
    return result;
  }

  public static BigInteger hash(String data){
    byte[] result = hash("MD5", data.getBytes());
    BigInteger hash = new BigInteger(result);
    return hash.abs();
  }

  public static void main(String[] args){
    while(cin.hasNext()){
      String str1=cin.next();
      BigInteger a= hash(str1);
      System.out.println(a);
    }
  }
}
D:>java get_md5
ningoo
100335222541762605209205022078301814192
江枫
48295316926871024838894171432474082043

OrderPreservingPartitioner:如果要支持针对Key的范围查询,那么可以选择这种有序分区策略。该策略采用的是字符串类型的Token。每个节点的具体选择需要根据Key的情况来确定。如果没有指定InitialToken,则系统会使用一个长度为16的随机字符串作为Token,字符串包含大小写字符和数字。

CollatingOrderPreservingPartitioner:和OrderPreservingPartitioner一样是有序分区策略。只是排序的方式不一样,采用的是字节型Token,支持设置不同语言环境的排序方式,代码中默认是en_US。

分区策略和每个节点的Token(Initial Token)都可以在storage-conf.xml配置文件中设置:

<Partitioner>org.apache.cassandra.dht.RandomPartitioner</Partitioner>
<InitialToken>10633823966279300000000000000000000000</InitialToken>

节点初始化完成以后,Token值做为元数据会保留在system keyspace中,每次启动会以该值为准,即使再改动配置文件中的InitialToken也不会产生任何影响。

Saved Token found: 10633823966279300000000000000000000000

通过nodetool的ring命令,可以查看集群各个节点的Token,这些Token值最好备份下来,当出现节点彻底顺坏时,可以重新设置同样的Token,确保数据分布可以不受节点损坏的影响。

 nodetool -h test ring
Address       Status     Load          Range                                      Ring
                                       85070591730234600000000000000000000000
192.168.0.1 Up         0 bytes       10633823966279300000000000000000000000     |<--|
192.168.0.2 Up         0 bytes       85070591730234600000000000000000000000     |-->|

PS: 在我的0.6.2的一个测试集群中,使用nodetool时不小心连到了9160端口,结果每次都会把节点搞挂,百试百灵。而且直接telnet到9160端口,随便发送个字符,也会把节点搞崩溃。不知道是我的测试环境的原因,还是Thrift有bug,这样节点的健壮性就有问题了,这个端口只能接受协议格式内的信息。对Java和Thrift都不太了解,把这个问题抛出来,希望有大牛能帮忙找到原因。

Update:之前贴的nodetool错连9160端口的报错可能有点误导大家,因为jmx用的默认的8080端口,连9160端口jmx报错是正常的,问题是节点不应该崩溃的。看了/var/log/cassandra/system.log中记录的节点错误信息,报的是OOM,Cassandra的java进程都消失了。调整了一下jvm参数,将heap的最小内存从默认的256MB设置到1G(-Xms1G),还是有同样的问题。另外,我的java环境是jre1.6.0_18。

ERROR [pool-1-thread-1] 2010-06-12 16:49:40,459 CassandraDaemon.java (line 78)
Fatal exception in thread Thread[pool-1-thread-1,5,main]
java.lang.OutOfMemoryError: Java heap space
        at org.apache.thrift.protocol.TBinaryProtocol.readStringBody(TBinaryProtocol.java:296)
        at org.apache.thrift.protocol.TBinaryProtocol.readMessageBegin(TBinaryProtocol.java:203)
        at org.apache.cassandra.thrift.Cassandra$Processor.process(Cassandra.java:1113)
        at org.apache.thrift.server.TThreadPoolServer$WorkerProcess.run(TThreadPoolServer.java:253)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

Google了一把这个错误,也有人碰到过,并且发现Thrift确实有类似的bug:
https://issues.apache.org/jira/browse/THRIFT-601

参考文档:
http://wiki.apache.org/cassandra/Operations

Oracle如何监控表的DML次数

数据库技术大会上,做了《构建高可用数据库监控系统》的分享以后,很多朋友对北斗如何实现表的DML次数监控有兴趣,会上因为时间的原因,我只是说有系统视图可以查到这个信息,因此有了本文,可以稍微详细一点来说明是如何实现的。

我说的系统视图,具体指的是dba_tab_modifications/all_tab_modifications/user_tab_modifications,这几个视图收集了表自从上一次分析之后的DML累积次数。但是要注意,考虑到性能的影响,Oracle并不是实时统计这个数据的,在Oracle9i之前,约3个小时SMON进程会刷新一次数据,而Oracle9i以后这个时间间隔变成了15分钟。

因此以较高的频率来实时监控这个表的话,得到的并不是当前的准确数据。Oracle在dbms_stat包中提供了一个过程来手动刷新统计数据,假如在一天的业务低峰期采集一次数据的话,可以先执行该过程,就能得到较为准确的数据。但是,不建议在业务高峰期执行该过程。

exec DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO;

在Oracle10g之前,必须手工开启表的monitoring属性,才会将DML统计信息收集到这个视图中。可以通过dba_tables.monitoring列查看表是否已经开启了监控。关于这个变化,可以参考Metalink ID 252597.1

alter table test monitoring;

Oracle10g之后,只要statistics_level是TYPICAL(默认)或者ALL,就能自动收集信息了,即使给表设置为nomonitoring也不能阻止,这个表的属性已经被废弃了。

desc dba_tab_modifications
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 TABLE_OWNER                                        VARCHAR2(30)
 TABLE_NAME                                         VARCHAR2(30)
 PARTITION_NAME                                     VARCHAR2(30)
 SUBPARTITION_NAME                                  VARCHAR2(30)
 INSERTS                                            NUMBER
 UPDATES                                            NUMBER
 DELETES                                            NUMBER
 TIMESTAMP                                          DATE
 TRUNCATED                                          VARCHAR2(3)
 DROP_SEGMENTS                                      NUMBER

遭遇Oracle11gR2 ASM文件无法扩展的Bug

在一个11gR2+ASM的环境中,因为产生了大量归档,导致控制文件需要扩展,结果数据库报错:

Errors in file /opt/oracle/diag/rdbms/test/test/trace/test_arc0_11146.trc:
ORA-00202: control file: '+DATA/control01.ctl'
ORA-17505: ksfdrsz:1 Failed to resize file to size 1920 blocks
ORA-15061: ASM operation not supported [41]
Control file expansion from 1600 blocks to 1920 blocks denied by OS

这是ASM的一个bug 8898852,可以在Oracle Support上找到对应的小patch,经过验证可以解决该问题。该patch已经包含在前两天刚发布的ASM的PSU中,只需要安装该PSU即可。

从目前我们使用11gR2的一些经验来看,bug还是比较多,尤其是一些影响比较大的bug,还是让人对11gR2无法完全放心,只能在特定的环境,和有足够容错方案的环境中,才能冒着风险来试用。

除了这个ASM文件不能扩展,有几个从10.2.0.4升级到11.2.0.1的库,在switchover中碰到了两次ORA-600 [ktbdchk1: bad dscn],出现问题后无法执行DML,非常严重的一个问题,并且暂时还没有好的办法解决,只能通过重建有问题的表的方式绕过,因为两次都是在切换后出现,初步推断是Active Data Guard带来的bug,开了SR和Oracle扯了很久,还在继续研究中。

据说Oracle 11.2.0.2将在年中发布,希望这个新的版本能更稳定些吧。

4月份,Oracle11.2.0.1的PSU和ASM(Grid Infrastructure)的第一个PSU都已经发布了,如果需要在产品环境中使用,建议这些PSU都打上吧

Oracle Database PSU Unix Patch Comments

11.2.0.1.1

Patch 9352237

11.2.0.1.1 for GI

Patch 9343627

11.1.0.7.3

Patch 9352179

11.1.0.7.2 for CRS

Patch 9207257

Released in January 2010

10.2.0.4.4

Patch 9352164

10.2.0.4.4 for CRS

Patch 9294403

注:该表格摘自My Oracle Support Note: 854428.1l


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

最新评论 | Recent comments

  • guanghui: 我很早就开始关注zfs,然后自然也关...
  • thomas zhang: 这个bug是够恶心的 官方11.2.0.2 Release...
  • 巫师勋: 这里面有一些理念和ASM很像啊,确实...
  • 大头刚: EXT4 对内核的要求太高,大规模的迁...
  • ruochen: ext4的稳定性现在应该说已经很不错了...
  • Rain@DNA: 是的,目前的一些主流版本里已经集...
  • icavy: 这里探讨 404错...
  • 驾照: 哥们挺厉害的。我练了好久,倒桩和...
  • icavy: 现在不用穿墙也可以...
  • NinGoo: @supsyg 这个应该是tnsname本身有问题吧...
  • supsyg: 试了一下,速度还不错,但tns连接好...
  • 再现9527: 多开开就好,现在的驾校培养出来很...
  • 曾经的阿飞: sysbench可以使用oltp-table-size指定自动...
  • 曾经的阿飞: 你说concurrency参数是不是和sysbench的num...
  • ppg: 有车之人,羡慕啊,正努力赚钱中.....