扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
Hadoop
创新互联公司服务项目包括东莞网站建设、东莞网站制作、东莞网页制作以及东莞网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,东莞网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到东莞省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!
文件系统:文件系统是用来存储和管理文件,并且提供文件的查询、增加、删除等操作。
直观上的体验:在shell窗口输入 ls 命令,就可以看到当前目录下的文件夹、文件。
文件存储在哪里?硬盘
一台只有250G硬盘的电脑,如果需要存储500G的文件可以怎么办?先将电脑硬盘扩容至少250G,再将文件分割成多块,放到多块硬盘上储存。
通过 hdfs dfs -ls 命令可以查看分布式文件系统中的文件,就像本地的ls命令一样。
HDFS在客户端上提供了查询、新增和删除的指令,可以实现将分布在多台机器上的文件系统进行统一的管理。
在分布式文件系统中,一个大文件会被切分成块,分别存储到几台机器上。结合上文中提到的那个存储500G大文件的那个例子,这500G的文件会按照一定的大小被切分成若干块,然后分别存储在若干台机器上,然后提供统一的操作接口。
看到这里,不少人可能会觉得,分布式文件系统不过如此,很简单嘛。事实真的是这样的么?
潜在问题
假如我有一个1000台机器组成的分布式系统,一台机器每天出现故障的概率是0.1%,那么整个系统每天出现故障的概率是多大呢?答案是(1-0.1%)^1000=63%,因此需要提供一个容错机制来保证发生差错时文件依然可以读出,这里暂时先不展开介绍。
如果要存储PB级或者EB级的数据,成千上万台机器组成的集群是很常见的,所以说分布式系统比单机系统要复杂得多呀。
这是一张HDFS的架构简图:
client通过nameNode了解数据在哪些DataNode上,从而发起查询。此外,不仅是查询文件,写入文件的时候也是先去请教NameNode,看看应该往哪个DateNode中去写。
为了某一份数据只写入到一个Datanode中,而这个Datanode因为某些原因出错无法读取的问题,需要通过冗余备份的方式来进行容错处理。因此,HDFS在写入一个数据块的时候,不会仅仅写入一个DataNode,而是会写入到多个DataNode中,这样,如果其中一个DataNode坏了,还可以从其余的DataNode中拿到数据,保证了数据不丢失。
实际上,每个数据块在HDFS上都会保存多份,保存在不同的DataNode上。这种是牺牲一定存储空间换取可靠性的做法。
接下来我们来看一下完整的文件写入的流程:
大文件要写入HDFS,client端根据配置将大文件分成固定大小的块,然后再上传到HDFS。
读取文件的流程:
1、client询问NameNode,我要读取某个路径下的文件,麻烦告诉我这个文件都在哪些DataNode上?
2、NameNode回复client,这个路径下的文件被切成了3块,分别在DataNode1、DataNode3和DataNode4上
3、client去找DataNode1、DataNode3和DataNode4,拿到3个文件块,通过stream读取并且整合起来
文件写入的流程:
1、client先将文件分块,然后询问NameNode,我要写入一个文件到某个路径下,文件有3块,应该怎么写?
2、NameNode回复client,可以分别写到DataNode1、DataNode2、DataNode3、DataNode4上,记住,每个块重复写3份,总共是9份
3、client找到DataNode1、DataNode2、DataNode3、DataNode4,把数据写到他们上面
出于容错的考虑,每个数据块有3个备份,但是3个备份快都直接由client端直接写入势必会带来client端过重的写入压力,这个点是否有更好的解决方案呢?回忆一下mysql主备之间是通过binlog文件进行同步的,HDFS当然也可以借鉴这个思想,数据其实只需要写入到一个datanode上,然后由datanode之间相互进行备份同步,减少了client端的写入压力,那么至于是一个datanode写入成功即成功,还是需要所有的参与备份的datanode返回写入成功才算成功,是可靠性配置的策略,当然这个设置会影响到数据写入的吞吐率,我们可以看到可靠性和效率永远是“鱼和熊掌不可兼得”的。
潜在问题
NameNode确实会回放editlog,但是不是每次都从头回放,它会先加载一个fsimage,这个文件是之前某一个时刻整个NameNode的文件元数据的内存快照,然后再在这个基础上回放editlog,完成后,会清空editlog,再把当前文件元数据的内存状态写入fsimage,方便下一次加载。
这样,全量回放就变成了增量回放,但是如果NameNode长时间未重启过,editlog依然会比较大,恢复的时间依然比较长,这个问题怎么解呢?
SecondNameNode是一个NameNode内的定时任务线程,它会定期地将editlog写入fsimage,然后情况原来的editlog,从而保证editlog的文件大小维持在一定大小。
NameNode挂了, SecondNameNode并不能替代NameNode,所以如果集群中只有一个NameNode,它挂了,整个系统就挂了。hadoop2.x之前,整个集群只能有一个NameNode,是有可能发生单点故障的,所以hadoop1.x有本身的不稳定性。但是hadoop2.x之后,我们可以在集群中配置多个NameNode,就不会有这个问题了,但是配置多个NameNode,需要注意的地方就更多了,系统就更加复杂了。
俗话说“一山不容二虎”,两个NameNode只能有一个是活跃状态active,另一个是备份状态standby,我们看一下两个NameNode的架构图。
两个NameNode通过JournalNode实现同步editlog,保持状态一致可以相互替换。
因为active的NameNode挂了之后,standby的NameNode要马上接替它,所以它们的数据要时刻保持一致,在写入数据的时候,两个NameNode内存中都要记录数据的元信息,并保持一致。这个JournalNode就是用来在两个NameNode中同步数据的,并且standby NameNode实现了SecondNameNode的功能。
进行数据同步操作的过程如下:
active NameNode有操作之后,它的editlog会被记录到JournalNode中,standby NameNode会从JournalNode中读取到变化并进行同步,同时standby NameNode会监听记录的变化。这样做的话就是实时同步了,并且standby NameNode就实现了SecondNameNode的功能。
优点:
缺点:
Cassandra属于最近比较流行的一款NoSQL数据库 中给NoSQL的定义如下:
下一代的数据库产品应该具备这几点:非关系型的,分布式的,开源的,可以线性扩展的。这类数据库最初的目的在于提供现代网站可扩展的数据库解决方案。这个运动开始于2009年初,目前正在迅速的发展。这种类型的数据库具有:自由的schema,数据多处备份,简单的编程API,数据的最终一致性保证等等。所以我们将这种类型的数据库称为NoSQL(不仅仅是SQL,全称为“not only sql”)。
下面我们一起来看看如果分别在Windows和Linux环境下安装和部署Cassandra。
在WINDOWS上单机运行CASSANDRA
大多数人使用的OS都是Windows,所以如果只是想简单地测试一下Cassandra,我们可以直接在安装好JDK1.6的Windows系统上安装Cassandra,并进行简单的测试。
1 下载Cassandra
下载即可。目前最新的beta版本是0.6.0 b3,但是我们安装使用的最新的Release版本0.5.1。
2 安装Cassandra
将下载的压缩包解压,假设解压的位置是D:\apache-cassandra-0.5.1。
1 修改conf目录下的log4j.properties文件:
log4j.appender.R.File=D:\apache-cassandra-0.5.1\logs
2 修改conf目录下的storage-conf.xml文件:
CommitLogDirectoryD:\apache-cassandra-0.5.1\commitlog/CommitLogDirectory
DataFileDirectories
DataFileDirectoryD:\apache-cassandra-0.5.1\data/DataFileDirectory
/DataFileDirectories
CalloutLocationD:\apache-cassandra-0.5.1\callouts/CalloutLocation
StagingFileDirectoryD:\apache-cassandra-0.5.1\staging/StagingFileDirectory
3 设置系统的环境变量:
CASSANDRA_HOME=D:\apache-cassandra-0.5.1
3 启动Cassandra
运行bin目录下的cassandra.bat。如果看到:INFO - Starting up server gossip,那么恭喜你,Cassandra已经在你的本机启动起来了。
4 使用命令行进行简单的测试
运行bin目录下的cassandra-cli.bat。输入:connect localhost 9160,连接成功后可以看到下面的提示。
cassandra connect localhost 9160
line 1:18 missing SLASH at '9160'
Connected to localhost/9160
然后,我们可以参考README.txt文件中提供的范例进行测试:
cassandra set Keyspace1.Standard1['jsmith']['first'] = 'John'
Value inserted.
cassandra set Keyspace1.Standard1['jsmith']['last'] = 'Smith'
Value inserted.
cassandra set Keyspace1.Standard1['jsmith']['age'] = '42'
Value inserted.
cassandra get Keyspace1.Standard1['jsmith']
(column=age, value=42; timestamp=1249930062801)
(column=first, value=John; timestamp=1249930053103)
(column=last, value=Smith; timestamp=1249930058345)
Returned 3 rows.
cassandra
你也可以根据这篇文章《谈谈Cassandra的客户端》中的内容测试一下如何使用Java编写简单的程序和Cassandra交互。
在LINUX上运行CASSANDRA集群
如果需要真正在生产环境中使用Cassandra,我们需要搭建一个Cassandra集群,这样才能真正发挥出它作为NoSQL数据所应该具备的特性。
在Linux部署Cassandra的步骤基本与Windows上部署的类似,我们需要在每一台机器上安装JDK1.6,然后下载Cassandra,并修改log4j.properties和storage-conf.xml的配置文件和设置环境变量。不同的是,我们需要在storage-conf.xml文件中配置集群的信息:
1 配置集群
1 配置集群节点信息
Seeds
Seedhadoop2/Seed
Seedhadoop3/Seed
Seedhadoop4/Seed
Seedhadoop5/Seed
Seedhadoop6/Seed
Seedhadoop7/Seed
Seedhadoop8/Seed
Seedhadoop9/Seed
Seedhadoop10/Seed
/Seeds
2 配置集群节点之间交互的监听地址
直接留空即可:
ListenAddress/ListenAddress
3 配置Thrift Server监听的地址
直接留空即可:
ThriftAddress/ThriftAddress
4 配置集群的名称
每一个集群的名称都应该是不用的
ClusterNamegpcuster.cnblogs.com/ClusterName
5 开启节点自动加入集群的功能
AutoBootstraptrue/AutoBootstrap
6 配置数据的备份数
ReplicationFactor3/ReplicationFactor
7 调节Memory和Disk的性能
需要根据实际的情况来配置,可以参考Wiki。
2 运行Cassandra
在每一台节点上,运行bin/cassandra。如果看到:INFO - Starting up server gossip,说明启动成功。
本文主要内容是测试了不同NoSQL数据库在测试工具YCSB中的表现。我们选取了3款流行的内存(in-memory)数据库管理系统:Redis,Tarantool 以及 CouchBase,还有缓存系统Memchached。Memchached虽然不属于数据库管理系统但常作为快速存储系统使用。
测试环境由4台在Microsoft Azure Cloud中的虚拟机组成的计算机组组成。这些虚拟机同属于一个数据中心。nosql-1和nosql-2用作测试Tarantool和CouchBase,nosql-3和nosql-4用作测试Redis,Azure Redis Cache 以及 Memcached。这些机器都安装和配置了相应数据库和测试项目。虚拟机的配置为4核A3 CPU,7GB RAM,120GB硬盘。
数据库及设置
内存数据库管理系统会存储所有在主内存中的数据并在磁碟上进行持续更新操作;透过日志记录每个数据的修改以确保连贯性。由于是以append-only方式进行日志写入,因此它很少遇到瓶颈问题;读取/写入都不会造成频繁的磁碟头移动。
Redis在2009推出,目前的最新版本是3.0.5。我们这里使用的版本是3.0.4,以append-only(只附加)方式进行数据管理,与其配合使用的是Microsoft Azure Redis Cache工具。
Tarantool是一款开源NoSQL数据库管理系统。我们使用的是Tarantool 1.6.7-126-gb35aff9,日志采用write-ahead(先写)模式。Memcached是一款分布式内存缓存系统,这里使用是Memcached 1.4.14-0ubuntu9。
Couchbase Server是开源分布式NoSQL面向文档数据库,这里使用的版本是Couchbase 4.0.0-4047-1。
YCSB测试工具
Yahoo! Cloud Serving Benchmark(YCSB)是功能强大的NoSQL数据库性能测试工具,它提供了6种主要的负载工作类型,以字母A到F来区分。
负载A负责更新操作,极值是50/50的读写操作,如用于进行新近操作记录。负载B负责读取操作,极值是95/5的读写操作,如用于进行图片标签管理,多进行标签读取操作。负载C负载100%的读取操作,如用于进行用户属性获取。负载D以先进先出方式进行插入操作,如用户进行最新数据读取。负载E负责小范围记录读取而不是单个记录读取,如线程会话。负载F负责记录的读取,修改和写入,如用户信息管理。
我们对配置文件作了两处参数修改:数据条目recordcount设为200000,操作条目operationcount设为5000000。YCSB是多线程工具,我们将以8, 16, 32, 64, 128 及256 线程来进行测试。详细的测试脚本请点击这里进行下载。
下列测试结果图以颜色进行测试对象区分,
Tarantool (HASH) (蓝)
Tarantool (TREE)(浅蓝)
Redis (红)
Azure Redis Cache (橙)
Memcached (绿)
CouchBase(黑)
更多图片请点击[这里]查看。
结论
Tarantool在所有负载类型测试中皆取得了最优成绩。它创建了一个无锁内存引擎,以协同多任务方式进行操作而不是互斥或并行处理方式。根据以下性能图表现,我们的结论是Tarantool的高吞吐量处理是其最大优势之一。因此在多数场合下,Tarantool是用户的最佳选择。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流