Apache Cassandra,目前唯一的用于大数据的NoSQL数据库的结构,顺便解释NoSQL和Big data
2014-01-07 10:37
721 查看
ApacheCassandra,目前唯一的用于大数据的NoSQL数据库的结构,顺便解释NoSQL和Bigdata
QQ空间新浪微博腾讯微博更多2013年3月5日3310
转我文章需注明出处:
我不是标题党,先来说说ApacheCassandra,开源分布式数据库管理系统。它最初由Facebook开发,用于储存特别大的数据,后来变为开源项目。
Cassandra现在用于Netflix,eBay,Twitter,UrbanAirship,ConstantContact,Reddit,Cisco,OpenX,Digg,CloudKick,Ooyala等等等。这些公司的共同点都是由大量,活跃的数据需要管理。目前已知最大的Cassandra数据库是有个用户的超过300TB的数据data跑在400多台机器上.
曾经,Twitter的工程师瑞恩·金(RyanKing)在博客中直接说到:“公司的分析团队、运营团队以及基础建设团队正在使用Cassandra系统合作研发一款供Twitter后台以及客户共同使用的大规模实时数据分析产品。”
不过由于两三年前我们刚刚了解Cassandra时,尚未提出云计算BIGDATA这个概念,而在那个时候0.6版本出来之后,国内有个别厂商专门组织针对Cassandra的读写性能做了测试分析。当时是淘宝团队测试,而测试的结果显示写出色,读比较差,此后再也没有看到这个测试结果针对新版本的release有过更新。但是由于目前已经是1.2.2版本:ApacheCassandrais1.2.2(releasedon2013-02-25).。因此这其中的改进应该还是比较明显的。
ApacheCassandra有如下特点,博主我简单做一个小结:
1、Cassandra群集扩展性能
Cassandra是混合型的非关系的数据库,类似于Google的BigTable。Cassandra的主要特点就是它不是一个数据库,而是由一堆数据库节点共同构成的一个分布式网络服务,对Cassandra的一个写操作,会被复制到其它节点上去,对Cassandra的读操作,也会被路由到某个节点上面去读取。对于一个Cassandra群集来说,扩展性能是比较简单的事情,只管在群集里面添加节点就可以了。
Cassandra能够简单透明地在多个机器上进行扩展,它们可以是廉价的硬件组成的集群,而无需购买昂贵的服务器或者SAN存储。但同样重要的是,透明地按需扩展和缩减集群的能力,使得公司能够更好地利用云的灵活性,针对小型工作负载可以添加合适的计算能力。MySQL5.6是做不到的。
2、Cassandra与MongoDB
Cassandra的主要功能比Dynamo(分布式的Key-Value存储系统)更丰富,但支持度却不如文档存储MongoDB,MongoDB是介于关系数据库和非关系数据库之间的开源产品,是非关系数据库当中功能最丰富,最像关系数据库的。支持的数据结构非常松散,是类似json的bjson格式,因此可以存储比较复杂的数据类型。而Cassandra支持复杂的数据类型则比较麻烦。那次有越来越多的客户转向MongoDB。
3、跨数据中心集群能力
Cassandra的普及率在不断的升高,其中一个原因就是扩多数据中心组成单一集群的能力。可协调的一致性使得Cassandra能够在数据中心内部进行同步复制,同时异步复制到其他数据中心。另一方面,基于主机的复制由于限制往往会造成较大的延迟,即便多主复制在关系型数据库方面也无法解决这一问题,因为两步提交机制也需要多个round-trip。而通过多数据中心的无主复制,Cassandra能够对整个数据中心进行无缝的故障转移,并在电力或连接修复之后对未同步的机器进行修复。
4、性能
我们在此篇文章的篇首说过,测试结果显示Cassandra的写性能优异。基于B-tree的存储引擎(InnoDB和MyISAM)事实上并不适合传统磁盘和SSD,因为有很多小的随机写入操作。但为何关系型数据库又是如此强势呢,主要还是因为SQL语义。比如,INSERT或UPDATE需要首先进行一个行的读取以确保它是否存在。这也是为什么MySQL数据库的写性能在数据集增长的时候会随之下降的原因。即使是针对相对合适的数据集,在混合的工作负载之下,这一结果也会逐渐显现。
数据模型结构
Cassandra的数据模型是基于列族(ColumnFamily)的四维或五维模型。它借鉴了Amazon的Dynamo和Google'sBigTable的数据结构和功能特点,采用Memtable和SSTable的方式进行存储。在Cassandra写入数据之前,需要先记录日志(CommitLog),然后数据开始写入到ColumnFamily对应的Memtable中,Memtable是一种按照key排序数据的内存结构,在满足一定条件时,再把Memtable的数据批量的刷新到磁盘上,存储为
SSTable。
增加keyspace\colums\的方式我会在下面详述:
Cassandra的数据模型的基本概念:
1、Cluster:Cassandra的节点实例,它可以包含多个Keyspace
2、Keyspace:用于存放ColumnFamily的容器,相当于关系数据库中的Schema或database3.ColumnFamily:用于存放Column的容器,类似关系数据库中的table的概念4.SuperColumn:它是一个特列殊的Column,它的Value值可以包函多个Column5.Columns:Cassandra的最基本单位。由name,value,timestamp组成
写入和读取一个USER的信息
安装部署
安装比较简单,几乎没有什么困难。
1、日志目录,注意目录/var/log/cassandra/存在且可写,日志的配置在conf/log4j-server.properies:
这一行log4j.appender.R.File=\/var/log/cassandra/system.log
2、用户数据在:data_file_directories(/var/lib/cassandra/data),在配置文件conf/cassandra.yaml里查看。
3、配置内存:在文件里conf/cassandra-env.sh,如下行:
#MAX_HEAP_SIZE="4G"
#HEAP_NEWSIZE="800M"可根据实际情况调整。
4、bin/cassandra-f启动,CTRL+C停止
5、bin/cassandra-cli进入交互命令行,如下指令可供试用:
bin/cassandra-cli
Youshouldseethefollowingprompt,ifsuccessful:
Connectedto:"TestCluster"on127.0.0.1/9160 WelcometoCassandraCLIversion1.0.7 Type'help;'or'?'forhelp. Type'quit;'or'exit;'toquit. [default@unknown]
Youcanaccesstotheonlinehelpwith'help;'command.Commandsareterminatedwithasemicolon(';')inthecli.
[default@unknown]help;
First,createakeyspaceforyourtest.
[default@unknown]createkeyspaceDEMO; f53dff10-5bd8-11e1-0000-915a024292eb Waitingforschemaagreement... ...schemasagreeacrossthecluster [default@unknown]
Don'tforgettoaddasemicolon(';')atendofthecommand.
Second,authenticateyoutousetheDEMOkeyspace.
[default@unknown]useDEMO; Authenticatedtokeyspace:DEMO [default@DEMO]
Third,createaUserscolumnfamily:
[default@DEMO]createcolumnfamilyUsers ...withkey_validation_class='UTF8Type' ...andcomparator='UTF8Type' ...anddefault_validation_class='UTF8Type'; [default@DEMO]
NowyoucanstoredataintoUserscolumnfamily:
[default@DEMO]setUsers[1234][name]=scott; Valueinserted. Elapsedtime:10msec(s). [default@DEMO]setUsers[1234][password]=tiger; Valueinserted. Elapsedtime:10msec(s). [default@DEMO]
YouhaveinsertedarowintotheUserscolumnfamily.Therowkeyis'1234',andwesetvaluesfortwocolumnsintherow:'name',and'password'.
Nowlet'sfetchthedatayouinserted:
[default@DEMO]getUsers[1234]; =>(column=name,value=scott,timestamp=1350769161684000) =>(column=password,value=tiger,timestamp=1350769245191000) Returned2results. Elapsedtime:67msec(s). [default@DEMO]
集群配置
生成一个多节点的集群:Creatingamultinodecluster
Thedefaultcassandra.yamlprovidedwithcassandraisgreatforgettingupandrunningonasinglenode.However,itisinappropriateforuseinamulti-nodecluster.Theconfigurationandprocessherearethesimplestwaytocreateamulti-nodecluster,butmaynotbethebestwayinproductiondeployments.
准备第一个节点:Preparingthefirstnode
需要修改如下两个选项:Thedefaultcassandra.yamlusesthelocal,loopbackaddressasitslisten(inter-node)andThrift(clientaccess)addresses:listen_address:locahost rpc_address:localhost
Asthelistenaddressisusedforintra-clustercommunication,itmustbechangedtoaroutableaddresssotheothernodescanreachit.Forexample,assumingyouhaveanEthernetinterfacewithaddress192.168.1.1,youwouldchangethelistenaddresslike
so:
listen_address:192.168.1.1
TheThriftinterfacecanbeconfiguredusingeitheraspecifiedaddress,likethelistenaddress,orusingthewildcard0.0.0.0,whichcausescassandratolistenforclientsonallavailableinterfaces.Updateitaseither:
rpc_address:192.168.1.1
OrperhapsthismachinehasasecondNICwithip10.140.179.1andsoyousplitthetrafficfortheintra-clusternetworktrafficfromthethrifttrafficforbetterperformance:
rpc_address:10.140.179.1
IftheDNSentryforyourhostiscorrect,itissafetouseahostnameinsteadofanIPaddress.Similarly,theseedinformationshouldbechangedfromtheloopbackaddress:
seeds: -127.0.0.1
Becomes:
seeds: -192.168.1.1
Oncethesechangesaremade,simplyrestartcassandraonthisnode.Usenetstat(e.g.netstat-ant|grep7000)toverifycassandraislisteningontherightaddress.Lookforalinelikethis:
配完后,NETSTAT看一下开的端口7000:
tcp400192.168.1.1.7000*.*LISTEN
Ifnetstatstillshowscassandralisteningon127.0.0.1.7000,theneitherthepreviouscassandraprocesswasnotproperlykilledoryouarenoteditingthecassandra.yamlfilecassandraisactuallyusing.
准备剩下的节点:
Theothernodesintheringwilluseacassandra.yamlalmostidenticaltotheoneonyourfirstnode,sousethatconfigurationasthebaseforthesechangesratherthanthedefaultcassandra.yaml.Thefirstchangeistoturnonautomaticbootstrapping.Thiswillcausethenodetojointheringandattempttotakecontrolofarangeofthetokenspace:
auto_bootstrap:true
1.0.版本以上此项可以不管,默认开启为true.
Thesecondchangeistothelistenaddress,asitmustalsonotbetheloopbackandcannotbethesameasanyothernode.AssumingyoursecondnodehasanEthernetinterfacewiththeaddress192.168.2.1,setitslistenaddresswith:
listen_address:192.168.2.1
Finally,updatethetheThriftaddresstoacceptclientconnections,aswiththefirstnode,eitherwithaspecificaddressorthewildcard:
rpc_address:192.168.2.1
Or:
rpc_address:10.140.180.1
NotethatyoushouldleavetheSeedssectionoftheconfigurationasissothenewnodesknowtousethefirstnodeforbootstrapping.Oncethesechangesaremade,startcassandraonthenewnodeanditwVA,PHP,illautomaticallyjointhering,assignitself
aninitialtoken,andprepareitselftohandlerequests.
可以使用JAVA\PHP\RUBY\PYTHON连接,我只熟python,大概是下面这个样子,具体还要修改:
在Python中使用Cassandra需要Thrift来生成第三方Python库,生成方式:thrift--genpyinterface/cassandra.thrift,然后在Python代码中引入所需的Python库,生成的Python库提供了与Cassandra建立连接、读写数据时所需要的方法。
Python连接Cassandra,写入并读取数据。
fromthriftimportThrift fromthrift.transportimportTTransport fromthrift.transportimportTSocket fromthrift.protocol.TBinaryProtocolimport TBinaryProtocolAccelerated fromcassandraimportCassandra fromcassandra.ttypesimport* importtime importpprint defmain(): socket=TSocket.TSocket("192.168.10.2",9160) transport=TTransport.TBufferedTransport(socket) protocol=TBinaryProtocol.TBinaryProtocolAccelerated(transport) client=Cassandra.Client(protocol) pp=pprint.PrettyPrinter(indent=2) keyspace="Keyspace1" column_path=ColumnPath(column_family="Standard1",column="age") key="studentA" value="18" timestamp=time.time() try: #打开数据库连接 transport.open() #写入数据 client.insert(keyspace,key,column_path, value,timestamp,ConsistencyLevel.ZERO) #查询数据 column_parent=ColumnParent(column_family="Standard1") slice_range=SliceRange(start="",finish="") predicate=SlicePredicate(slice_range=slice_range) result=client.get_slice(keyspace,key,column_parent, predicate,ConsistencyLevel.ONE) pp.pprint(result) exceptThrift.TException,tx: print'Thrift:%s'%tx.message finally: #关闭连接 transport.close() if__name__=='__main__': main()
暂时说这么多,转帖请注明出处www.alexclouds.net.谢谢!
相关文章推荐
- 【NOSQL】非关系型数据库MongoDB ( 用MongoDB的文档结构描述数据关系 )
- 将数据库的树形结构的数据,转成JSON,用于树形列表显示
- ORACLE同一个数据库下不同表结构之间的数据导入
- 利用PLSQL Developer 数据库间表结构和数据对比
- 下载数据库表结构和数据
- JSON复杂数据处理之Json树形结构数据转Java对象并存储到数据库的实现
- 4.非关系型数据库(Nosql)之mongodb:普通索引,唯一索引
- 数据库分页时order by排序不唯一,分页出现重复数据问题
- 数据模型和数据库系统的模型结构
- Laravel学习笔记(五)数据库 数据库迁移案例2——创建数据结构,数据表,修改数据结构
- 将数据库中的数据生成插入语句(用于数据的导出与导入)
- 关于数据库和数据表的结构和数据记录对比方法
- 微信公号“架构师之路”学习笔记(五)-数据库扩展性架构设计(水平切分,秒级扩容,平滑迁移,在线表结构变更,一个大数据量多属性高并发的数据库设计等)
- poi+jdbc实现从数据库中导出表的数据字典结构(单个sheet和多个sheet供你选择),并且生成excel文档,作者:vipyhd
- 用于不同服务器数据库之间的数据操作
- 构建数据库数据的树状结构
- java代码删除数据库中树形结构数据
- Java 数据库之 redredis 使用----数据结构
- 数据库之表格的结构的更改以及数据的增、删、插、改
- 显示数据(从数据库中得到)中的html标签 用于解决数据在前台显示,样式被数据破坏的问题!!css