Apache Accumulo的是一个高度可扩展的结构化存储,基于谷歌的BigTable。Accumulo是用Java编写的,并在Hadoop分布式文件系统 (HDFS),这是流行的Apache Hadoop项目的一部分工做。Accumulo支持高效存储和检索的结构化数据,包括查询范围,并提供支持使用Accumulo表做为输入和输出的 MapReduce做业。java
Accumulo设有自动负载平衡和分区,数据压缩和细粒度的安全标签。web
Accumulo提供了丰富的数据模型不是简单的键 - 值存储,但不是彻底的关系数据库。数据表示为键 - 值对,其中键和值是由如下元素:正则表达式
Key算法 |
Valueshell |
|
Row ID数据库 |
Columnapache |
Timestamp编程 |
Family数组 |
Qualifier浏览器 |
Visibility |
键和值的全部元素都表示为字节数组时间戳,这是一个长期的除外。Accumulo各类键的元素和字典升序排列。时间戳以递减顺序排序,首先出如今一个连续的扫描,以便之后的版本相同的密钥。表由一组排序键 - 值对。
accumulo是一个分布式数据存储和检索系统,所以由一些建筑元件,其中一些许多单独服务器上运行的。大部分的工做确实涉及Accumulo保持必定性能的数据,如组织,可用性和完整性,在许多商品级机。
一个实例的Accumulo包括的许多TabletServers,一个垃圾收集过程当中,一台主服务器和多个客户端。
TabletServer 管理一些子集的全部片(分区表)。这包括接收从客户端中写道,坚持预写日志,写入新的键值对排序在内存中,按期冲洗排序键 - 值对HDFS中的新文件,并响应来自客户端的读取,造成一个合并排序查看全部键和值从建立和排序的内存中存储的全部文件。
TabletServers执行恢复之前的服务器失败,从新应用发现任何写在预写日志平板平板。
Accumulo进程将共享存储在HDFS中的文件。每隔一段时间,垃圾收集器将肯定再也不须要任何进程的文件,并删除它们。
是 负责检测和响应TabletServer失败的Accumulo master。它试图以平衡负载分配药片仔细和指导TabletServers的卸载片,必要时跨TabletServer的。master确保全部分片 被分配到每个TabletServer,并处理表的建立,修改和删除请求从客户。master也协调启动,正常关机和恢复的变化的预写日志tablet 服务器时失败。
可能会运行多个master。master将选举一个做为master,其余做为备份。
Accumulo包括连接到每个应用程序的客户端库。客户端库包含逻辑寻找管理某个特定的平板电脑,服务器和通讯与TabletServers写入和检索键 - 值对。
Accumulo 存储表中的数据,这是划分红片。片分区行边界,这样一个特定的行的全部列和值一块儿被发如今同一片剂。主片分配到一个TabletServer的时间。这使 行级交易采起不使用分布式锁或其余一些复杂的同步机制。随着客户的插入和查询数据,机器从集群中添加和删除,主迁移片来保证他们就仍然能够采集和查询负载 平衡群集。
写 在TabletServer到达时,它被写入到一个预写日志,而后插入称为MemTable中一个排序的数据结构在内存中。当MemTable对达到必定 规模的TabletServer写道排序键 - 值对在HDFS中的文件被称为索引顺序访问方法(ISAM)文件。这个过程被称为一个小压实。而后建立一个新的MemTable中预写日志记录和压实的事 实。
当 一个请求读取数据在TabletServer到达的,TabletServer确实二进制搜索以及整个MemTable中每一个ISAM文件在内存中的相关 指标,找到相关的值。若是客户端执行扫描,几个键 - 值对返回给客户端为了从MemTable中ISAM文件集进行合并排序,由于他们是阅读。
为了管理文件,每片的数量,按期TabletServer的执行主要压实tablet内的文件,其中一些ISAM文件合并成一个文件。最终将被删除之前的文件,由垃圾收集器。这也提供了一个机会,用来完全删除键 - 值对省略键 - 值对建立新的文件时,删除条目抑制。
当 建立一个表,它有一个平板电脑。随着表的增加,其最初的平板电脑最终分裂成两片。它多是这些药片将迁移到另外一台平板电脑服务器。如上表持续增加,及其片 剂将继续分裂和迁移。的决定是基于自动分割片剂的片剂的大小的文件。片剂分割的大小阈值配置的每一个表。除了自动分裂,用户能够手动添加的分割点,用来从表 中建立新的片剂。手动分裂一个新表能够并行的读取和写入操做提供更好的初始性能,而无需等待自动分割。
当数据从表中删除,平板电脑可能会萎缩。随着时间的推移,这可能会致使空或小片。为了处理这个问题,片剂合并被引入在1.4 Accumulo。这在后面更详细讨论。
若是TabletServer失败,法师检测,并自动从故障服务器分配到其余服务器从新分配片。任何键 - 值对,在内存中的时间TabletServer失败自动从新应用预写式日志,以防止丢失任何数据。
法师将协调预写日志复制到HDFS,以便提供给全部tablet服务器日志。为了使回收效率,更新在日志分组的平板电脑。注定的牌位,他们如今被分配给从排序的日志,能够快速申请TabletServers突变。
TabletServer故障都注意到法师的监控页面,经过http://master-address:50095/monitor
访问的 。
Accumulo提供了一个简单的shell,能够用来检查表的内容和配置设置,插入/更新/删除值,更改配置设置。
外壳能够开始下面的命令:
$ACCUMULO_HOME/bin/accumulo shell -u [username]
shell会提示输入相应的密码到指定的用户名,而后显示如下提示:
Shell - Apache Accumulo Interactive Shell - - version 1.5 - instance name: myinstance - instance id: 00000000-0000-0000-0000-000000000000 - - type 'help' for a list of available commands -
Accumulo shell能够用来建立和删除表,以及配置表和实例的具体选项。
root@myinstance> tables !METADATA
root@myinstance> createtable mytable
root@myinstance mytable>
root@myinstance mytable> tables !METADATA mytable
root@myinstance mytable> createtable testtable
root@myinstance testtable>
root@myinstance testtable> deletetable testtable
root@myinstance>壳牌也能够用来插入更新和扫描表。这是很是有用的检查表。root@myinstance mytable> scanroot@myinstance mytable> insert row1 colf colq value1 insert successfulroot@myinstance mytable> scan row1 colf:colq [] value1
括号内的数值“[]”的知名度标签。因为没有被使用,这是该行空。您可使用“-ST”扫描到细胞内,也看到时间戳选项。
compact命令指示Accumulo安排巩固和删除哪些文件项被删除的表压实。
root@myinstance mytable> compact -t mytable 07 16:13:53,201 [shell.Shell] INFO : Compaction of table mytable scheduled for 20100707161353EDT
该flush命令指示Accumulo写当前内存中的全部条目,对于一个给定的表到磁盘。
root@myinstance mytable> flush -t mytable 07 16:14:19,351 [shell.Shell] INFO : Flush of table mytable initiated...
shell可用于添加,删除,并授予用户特权。
root@myinstance mytable> createuser bob Enter new password for 'bob': ********* Please confirm new password for 'bob': *********
root@myinstance mytable> authenticate bob Enter current password for 'bob': ********* Valid
root@myinstance mytable> grant System.CREATE_TABLE -s -u bob
root@myinstance mytable> user bob Enter current password for 'bob': *********
bob@myinstance mytable> userpermissions System permissions: System.CREATE_TABLE Table permissions (!METADATA): Table.READ Table permissions (mytable): NONE
bob@myinstance mytable> createtable bobstable bob@myinstance bobstable>
bob@myinstance bobstable> user root Enter current password for 'root': *********
root@myinstance bobstable> revoke System.CREATE_TABLE -s -u bob
有多种方式运行的Java代码使用Accumulo的。下面列出的不一样的方式来执行客户端代码。
使用Java可执行文件
使用accumulo脚本
使用该工具的脚本
为 了运行客户端代码编写对Accumulo运行,您将须要包括罐子Accumulo取决于你的classpath。Accumulo客户端的代码依赖于 Hadoop和饲养员。对于Hadoop的Hadoop的核心罐子,在Hadoop的lib目录下的全部的罐子,conf目录到classpath中。饲 养员3.3,你只须要添加饲养员罐,也不是什么在饲养员的lib目录。您能够运行下面的命令上的配置Accumulo系统,看看有什么使用它的类路径。
$ACCUMULO_HOME/bin/accumulo classpath
运行你的代码的另外一种选择是把一个jar文件 $ ACCUMULO_HOME / lib / ext目录
。这样作后,你可使用accumulo的脚原本执行你的代码。例如,若是你建立一个jar含有类com.foo.Client,放置在lib / ext目录
,那么你可使用命令 $ ACCUMULO_HOME / bin中/ accumulo com.foo.Client的
执行代码。
若是你正在写的地图减小,访问Accumulo,那么你可使用的bin / tool.sh的脚原本运行这些做业的工做。查看地图减小的例子。
全部客户端必须先识别Accumulo例如,他们将进行通讯。作到这一点的代码以下:
String instanceName = "myinstance";String zooServers = "zooserver-one,zooserver-two"Instance inst = new ZooKeeperInstance(instanceName, zooServers);Connector conn = inst.getConnector("user", "passwd");
经过建立对象表明全部更改的列单排突变数据写入到Accumulo的。这些变化是由原子在TabletServer。客户端,而后将它提交给适当的TabletServers到BatchWriter突变。
突变能够建立这样的:
Text rowID = new Text("row1");Text colFam = new Text("myColFam");Text colQual = new Text("myColQual");ColumnVisibility colVis = new ColumnVisibility("public");long timestamp = System.currentTimeMillis();Value value = new Value("myValue".getBytes());Mutation mutation = new Mutation(rowID); mutation.put(colFam, colQual, colVis, timestamp, value);
高度优化的BatchWriter送突变的多个TabletServers和自动批次突变摊销网络开销相同TabletServer注定。必须当心避免的任何传递给BatchWriter对象改变的内容,由于它保持内存中的对象,而配料。
添加到BatchWriter突变是这样的:
long memBuf = 1000000L; // bytes to store before sending a batchlong timeout = 1000L; // milliseconds to wait before sendingint numThreads = 10;BatchWriter writer = conn.createBatchWriter("table", memBuf, timeout, numThreads) writer.add(mutation); writer.close();
一个例子能够发如今使用批处理写 accumulo/docs/examples/README.batch
Accumulo优化,快速检索与给定键关联的值,并有效返回连续键及其关联值范围。
检索数据,客户端使用扫描仪,它的做用像一个迭代器键和值。扫描仪能够被配置在特定的键来启动和中止,并返回可用的列的一个子集。
// specify which visibilities we are allowed to seeAuthorizations auths = new Authorizations("public");Scanner scan = conn.createScanner("table", auths); scan.setRange(new Range("harry","john")); scan.fetchFamily("attributes");for(Entry<Key,Value> entry : scan) { String row = entry.getKey().getRow(); Value value = entry.getValue(); }
Accumulo支持能力提出了一个孤立的观点的行扫描时。有三种可能的方式,行可能会改变accumulo:
一个突变应用于一个表
或大或小的压实的一部分执行的迭代器
批量导入新文件
隔 离担保,全部这些操做的行上所作的更改或无被看见。使用IsolatedScanner孤立的观点的一个accumulo表取得。当使用常规的扫描仪,它 是能够看到一排的非孤立的观点。例如,若是一个突变修改分三路,它多是你只会看到两个修改。对于隔离扫描仪要么所有三个的变化被视为或无。
该IsolatedScanner缓冲行客户端上的,因此不会大排平板服务器崩溃。默认状况下,行缓存在内存中,但用户能够方便地提供本身的缓冲区,若是他们想缓冲到磁盘时行大。
举一个例子,看看
examples/simple/src/main/java/org/apache/accumulo/examples/simple/isolation/InterferenceTest.java
对于某些类型的访问,它是更有效的同时检索几个范围。出现这种状况,当访问一组不连续的行,其ID已检索,例如从二级索引。
类 似该BatchScanner配置到扫描器,它能够被配置为检索可用的列的一个子集,可是,而不是经过一个单一的范围,BatchScanners接受一 组范围。重要的是要注意,键由BatchScanner返回键以排序的顺序,由于流式传输是从多个TabletServers平行。
ArrayList<Range> ranges = new ArrayList<Range>();// populate list of ranges ...BatchScanner bscan = conn.createBatchScanner("table", auths, 10); bscan.setRanges(ranges); bscan.fetchFamily("attributes");for(Entry<Key,Value> entry : scan) System.out.println(entry.getValue());
一个例子能够发如今accumulo/docs/examples/README.batch
代理API容许Java之外的语言与Accumulo互动。在代码库中提供代理服务器和一个客户端能够进一步产生。
代理服务器能够住在任何节点上的基本客户端API将工做。这意味着它必须是可以沟通的法师,饲养员,NameNode的数据节点。代理客户端只须要与代理服务器进行通讯的能力。
代理服务器的配置选项里面住的属性文件。最起码,你须要提供如下属性:
protocolFactory=org.apache.thrift.protocol.TCompactProtocol$Factory tokenClass=org.apache.accumulo.core.client.security.tokens.PasswordToken port=42424 instance=test zookeepers=localhost:2181
在你的发行版,你能够找到一个示例配置文件:
$ACCUMULO_HOME/proxy/proxy.properties
这个配置文件示例演示备份代理服务器由MockAccumulo或MiniAccumuloCluster的的abilty。
控股配置属性文件建立后,代理服务器就能够开始在Accumulo分布(假设你的属性文件被命名为config.properties中)使用如下命令:
$ACCUMULO_HOME/bin/accumulo proxy -p config.properties
除了安装旧货编译的,你还须要生成客户端代码,语言旧货安装特定语言的库。一般状况下,您的操做系统的软件包管理器就能自动安装这些你在预期的位置,如目录/ usr / lib中/蟒蛇/节俭的site-packages /。
你能够找到节俭文件生成客户端:
$ACCUMULO_HOME/proxy/proxy.thrift
生成客户端后,在上述的配置属性指定的端口将被用来链接到服务器。
下面的例子已经写在Java和方法签名可能旧货编译器生成客户端时指定的语言不一样而略有差异。在初始化一个链接到代理服务器(Apache旧货的文件链接到旧货服务的例子),代理客户机上的方法将可用。要作的第一件事就是登陆:
Map password = new HashMap<String,String>(); password.put("password", "secret");ByteBuffer token = client.login("root", password);
登陆后,返回的令牌将被使用到客户端的后续调用。让咱们建立一个表,添加一些数据,表扫描,并删除它。
首先,建立一个表。
client.createTable(token, "myTable", true, TimeType.MILLIS);
接下来,添加一些数据:
// first, create a writer on the serverString writer = client.createWriter(token, "myTable", new WriterOptions());// build column updatesMap<ByteBuffer, List<ColumnUpdate> cells> cellsToUpdate = //...// send updates to the serverclient.updateAndFlush(writer, "myTable", cellsToUpdate); client.closeWriter(writer);
扫描数据和批处理的服务器上返回的结果:
String scanner = client.createScanner(token, "myTable", new ScanOptions());ScanResult results = client.nextK(scanner, 100);for(KeyValue keyValue : results.getResultsIterator()) { // do something with results} client.closeScanner(scanner);
一般状况下,Accumulo包含许多移动部件。即便是一个单机版的Hadoop的Accumulo须要,动物园管理员,Accumulo高手,tablet服务器等,若是你想写单元测试使用Accumulo的,你须要大量的基础设施到位以前,你的测试能够运行。
模拟Accumulo用品大部分的客户端API模拟实现。它目前不强制用户,登陆权限,等它支持迭代器和组合。请注意,MockAccumulo保存在内存中的全部数据,并不会保留任何数据或设置运行之间。
在正常状况下与Accumulo客户端的交互看起来像这样:
Instance instance = new ZooKeeperInstance(...);Connector conn = instance.getConnector(user, passwordToken);
要与MockAccumulo互动时,只需更换ZooKeeperInstance与MockInstance:
Instance instance = new MockInstance();
事实上,你可使用选项-假
的Accumulo壳与MockAccumulo:
$ ./bin/accumulo shell --fake -u root -p '' Shell - Apache Accumulo Interactive Shell - - version: 1.5 - instance name: fake - instance id: mock-instance-id - - type 'help' for a list of available commands - root@fake> createtable test root@fake test> insert row1 cf cq value root@fake test> insert row2 cf cq value2 root@fake test> insert row3 cf cq value3 root@fake test> scan row1 cf:cq [] value row2 cf:cq [] value2 row3 cf:cq [] value3 root@fake test> scan -b row2 -e row2 row2 cf:cq [] value2 root@fake test>
当测试的Map Reduce做业,你还能够设置的的AccumuloInputFormat和AccumuloOutputFormat类的模拟Accumulo:
AccumuloInputFormat.setMockInstance(job, "mockInstance"); AccumuloOutputFormat.setMockInstance(job, "mockInstance");
虽 然模拟Accumulo的进行单元测试的客户端API提供了一个轻量级的实施,每每是必要写更现实的终端到终端的整合利用整个生态系统的测试。的迷你 Accumulo集群配置和启动饲养员,初始化Accumulo,并开始主以及一些平板电脑服务器,使这成为可能。它的运行对本地文件系统,而没必要启动 HDFS。
启动它,你将须要做为参数提供一个空的目录和根密码:
File tempDirectory = // JUnit and Guava supply mechanisms for creating temp directoriesMiniAccumuloCluster accumulo = new MiniAccumuloCluster(tempDirectory, "password"); accumulo.start();
一旦咱们有咱们的小集群运行,咱们将要与客户端API Accumulo:
Instance instance = new ZooKeeperInstance(accumulo.getInstanceName(), accumulo.getZooKeepers());Connector conn = instance.getConnector("root", new PasswordToken("password"));
完成后,咱们的开发代码,咱们想关闭咱们MiniAccumuloCluster:
accumulo.stop()// delete your temporary folder
Accumulo表中有几个选项来改变默认行为,Accumulo以及存储的数据的基础上提升性能,能够配置。这些措施包括地方团体,约束,怒放的过滤器,迭代器和块缓存。
Accumulo套柱家庭支持存储在磁盘上分开,以容许客户端有效地扫描是常常一块儿使用,以免扫描列家庭不要求列。地址组设置后,会自动利用扫描仪和BatchScanner操做时,他们的fetchColumnFamilies()方法用于。
默认状况下,表放置到同一个“默认”本地组的全部列家庭。随时能够配置其余地方团体经过shell或编程方式以下:
usage: setgroups <group>=<col fam>{,<col fam>}{ <group>=<col fam>{,<col fam>}} [-?] -t <table>
user@myinstance mytable> setgroups group_one=colf1,colf2 -t mytable
user@myinstance mytable> getgroups -t mytable
Connector conn;HashMap<String,Set<Text>> localityGroups = new HashMap<String, Set<Text>>();HashSet<Text> metadataColumns = new HashSet<Text>(); metadataColumns.add(new Text("domain")); metadataColumns.add(new Text("link"));HashSet<Text> contentColumns = new HashSet<Text>(); contentColumns.add(new Text("body")); contentColumns.add(new Text("images")); localityGroups.put("metadata", metadataColumns); localityGroups.put("content", contentColumns); conn.tableOperations().setLocalityGroups("mytable", localityGroups);// existing locality groups can be obtained as followsMap<String, Set<Text>> groups = conn.tableOperations().getLocalityGroups("mytable");
列的家庭地址组的分配能够在任什么时候间改变。的物理移动到他们的新地址组的列家庭主要经过按期压实过程,发生在后台持续发生。主要压实,也可如期经过shell当即生效:
user@myinstance mytable> compact -t mytable
Accumulo支持突变在插入时的约束。这能够被用来根据用户定义的策略禁止某些插入。不限突变不符合要求的约束被拒绝,而且发送回客户端。
约束能够经过设置表属性以下:
user@myinstance mytable> constraint -t mytable -a com.test.ExampleConstraint com.test.AnotherConstraint user@myinstance mytable> constraint -l com.test.ExampleConstraint=1 com.test.AnotherConstraint=2
目前,有没有通用的约束与Accumulo分布。新的约束条件,能够建立经过编写Java类实现org.apache.accumulo.core.constraints.Constraint接口的。
要部署一个新的约束,建立一个jar文件包含的类实施新的约束,并将其放置在lib目录的Accumulo安装。能够添加新的约束罐到Accumulo,不从新启动的状况下启动,但现有的约束类的任何改变须要从新启动Accumulo。
约束的一个例子能够发如今 accumulo/docs/examples/README.constraints
相应的代码,根据 accumulo/examples/simple/main/java/accumulo/examples/simple/constraints
。
突变被应用到一个Accumulo表,每片建立几个文件。若是怒放的过滤器被启用,Accumulo将建立并加载到内存中的一个小的数据结构,以肯定文件是否包含给定键在打开文件以前。这能够大大加快查找。
为了使怒放的过滤器,壳牌输入如下命令:
user@myinstance> config -t mytable -s table.bloom.enabled=true
普遍使用bloom过滤器的例子能够发如今accumulo/docs/examples/README.bloom
.。
迭代器提供了一个模块化的机制,用于将要执行的TabletServers功能进行扫描,或者数据压缩。这使用户可以有效地总结,筛选和汇总数据。事实上,内置的单元级别的安全功能和列取使用迭代器来实现。一些有用的迭代器中所提供与Accumulo和中能够找到的 org.apache.accumulo.core.iterators.user
包。在每一种状况下,任何自定义的迭代器必须包括在Accumulo classpath中,一般包括一个罐子在$ ACCUMULO_HOME / lib中
或 $ ACCUMULO_HOME / lib / ext目录
,虽然VFS类加载器容许类路径操纵利用的各类计划,包括网址和HDFS的URI 。
迭代器能够配置的桌子上扫描,小型压实和/或主要压实范围。若是迭代实现的OptionDescriber接口,的setiter命令可用于交互的方式提示用户提供值给予必要的选项。
usage: setiter [-?] -ageoff | -agg | -class <name> | -regex | -reqvis | -vers [-majc] [-minc] [-n <itername>] -p <pri> [-scan] [-t <table>]
user@myinstance mytable> setiter -t mytable -scan -p 15 -n myiter -class com.company.MyIterator
config命令能够随时用于手动配置了Iterator不实施的OptionDescriber接口的状况下,这是很是有用的迭代器。
config -t mytable -s table.iterator.{scan|minc|majc}.myiter=15,com.company.MyIterator config -t mytable -s table.iteartor.{scan|minc|majc}.myiter.opt.myoptionname=myoptionvalue
scanner.addIterator(new IteratorSetting( 15, // priority "myiter", // name this iterator "com.company.MyIterator" // class name));
一些迭代器从客户端代码须要额外的参数,以下面的例子:
IteratorSetting iter = new IteratorSetting(...); iter.addOption("myoptionname", "myoptionvalue"); scanner.addIterator(iter)
表支持独立的迭代器设置被应用在扫描时轻微压实后,而主要压实。对于大多数用途,表格将具备相同的全部三个迭代器设置,以免不一致的结果。
Accumulo 提供版本的数据管理能力,经过使用时间戳内的关键。由客户端建立的关键,若是没有指定一个时间戳,而后系统将设置时间戳为当前时间。两个键具备相同的 ROWID列,但不一样的时间戳被认为是两个版本的相同的密钥。若是两个插入相同的ROWID,列和时间戳制成accumulo的,则行为是不肯定性。
时间戳以递减顺序排序,最新的数据是第一位的。accumulo能够配置为返回前k个版本,或版本高于给定的日期。默认是返回一个最新版本。
是能够改变的经过改变VersioningIterator选项以下的表的版本政策:
user@myinstance mytable> config -t mytable -s table.iterator.scan.vers.opt.maxVersions=3 user@myinstance mytable> config -t mytable -s table.iterator.minc.vers.opt.maxVersions=3 user@myinstance mytable> config -t mytable -s table.iterator.majc.vers.opt.maxVersions=3
建立表时,默认状况下,它的配置,使用VersioningIterator和保持一个版本。能够建立一个表不VersioningIterator NDI选项在shell。的Java API还具备如下的方法
connector.tableOperations.create(String tableName, boolean limitVersion)
Accumulo 1.2引入逻辑时间的概念。这确保由accumulo设置时间戳永远向前。这将有助于避免出现问题由TabletServers引发不一样的时间设置。每片 计数器时间邮票每个突变的基础上给出了独特的一。当使用时间以毫秒为单位,若是两件事情同一毫秒内到达,而后都收到相同的时间戳。当使用时间(以毫秒为 单位),将accumulo设定的时间始终前进,永不后退。
表能够配置为使用逻辑在建立时的时间戳以下:
user@myinstance> createtable -tl logical
删除特殊键accumulo获得沿将全部其余数据排序。当删除键被插入时,accumulo将不显示任何有时间戳小于或等于删除键。在主要压实,年纪比任何键删除键被省略建立的新文件,并省略键做为正规的垃圾收集过程的一部分从磁盘上删除。
键 -值对的一组扫描时,它是经过一个过滤器的使用,能够将任意的过滤策略。过滤器是只返回键-值对知足过滤逻辑的迭代器类型。Accumulo有几个内置的 过滤器,能够配置任何表:ColumnAgeOff AgeOff,时间戳,NoVis,和正则表达式。能够添加更多经过编写一个Java类扩展 org.apache.accumulo.core.iterators.Filter
类。
该AgeOff过滤器能够被配置为删除的数据比目标日期或一个固定的时间量从本。下面的例子设置一个表中删除插入超过30秒前的一切:
user@myinstance> createtable filtertest user@myinstance filtertest> setiter -t filtertest -scan -minc -majc -p 10 -n myfilter -ageoff AgeOffFilter removes entries with timestamps more than <ttl> milliseconds old ----------> set org.apache.accumulo.core.iterators.user.AgeOffFilter parameter negate, default false keeps k/v that pass accept method, true rejects k/v that pass accept method: ----------> set org.apache.accumulo.core.iterators.user.AgeOffFilter parameter ttl, time to live (milliseconds): 3000 ----------> set org.apache.accumulo.core.iterators.user.AgeOffFilter parameter currentTime, if set, use the given value as the absolute time in milliseconds as the current time of day: user@myinstance filtertest> user@myinstance filtertest> scan user@myinstance filtertest> insert foo a b c user@myinstance filtertest> scan foo a:b [] c user@myinstance filtertest> sleep 4 user@myinstance filtertest> scan user@myinstance filtertest>
看到一个表的迭代器设置,使用方法:
user@example filtertest> config -t filtertest -f iterator ---------+---------------------------------------------+------------------ SCOPE | NAME | VALUE ---------+---------------------------------------------+------------------ table | table.iterator.majc.myfilter .............. | 10,org.apache.accumulo.core.iterators.user.AgeOffFilter table | table.iterator.majc.myfilter.opt.ttl ...... | 3000 table | table.iterator.majc.vers .................. | 20,org.apache.accumulo.core.iterators.VersioningIterator table | table.iterator.majc.vers.opt.maxVersions .. | 1 table | table.iterator.minc.myfilter .............. | 10,org.apache.accumulo.core.iterators.user.AgeOffFilter table | table.iterator.minc.myfilter.opt.ttl ...... | 3000 table | table.iterator.minc.vers .................. | 20,org.apache.accumulo.core.iterators.VersioningIterator table | table.iterator.minc.vers.opt.maxVersions .. | 1 table | table.iterator.scan.myfilter .............. | 10,org.apache.accumulo.core.iterators.user.AgeOffFilter table | table.iterator.scan.myfilter.opt.ttl ...... | 3000 table | table.iterator.scan.vers .................. | 20,org.apache.accumulo.core.iterators.VersioningIterator table | table.iterator.scan.vers.opt.maxVersions .. | 1 ---------+---------------------------------------------+------------------
Accumulo容许合路器上配置表和列家庭。合当它应用于跨股份ROWID列家庭和列预选赛任何键关联的值。这是相似MapReduce的减小步骤,应用一些函数与特定键相关联的全部的值。
例如,若是一个加法组合器被配置在桌子上,如下的突变,插入
Row Family Qualifier Timestamp Value rowID1 colfA colqA 20100101 1 rowID1 colfA colqA 20100102 1
该表将反映只有一个总价值:
rowID1 colfA colqA - 2
合路器可使用一个表的setiter在shell命令启用。下面就是一个例子。
root@a14 perDayCounts> setiter -t perDayCounts -p 10 -scan -minc -majc -n daycount -class org.apache.accumulo.core.iterators.user.SummingCombiner TypedValueCombiner can interpret Values as a variety of number encodings (VLong, Long, or String) before combining ----------> set SummingCombiner parameter columns, <col fam>[:<col qual>]{,<col fam>[:<col qual>]} : day ----------> set SummingCombiner parameter type, <VARNUM|LONG|STRING>: STRING
root@a14 perDayCounts> insert foo day 20080101 1 root@a14 perDayCounts> insert foo day 20080101 1 root@a14 perDayCounts> insert foo day 20080103 1 root@a14 perDayCounts> insert bar day 20080101 1 root@a14 perDayCounts> insert bar day 20080101 1
root@a14 perDayCounts> scan bar day:20080101 [] 2 foo day:20080101 [] 2 foo day:20080103 [] 1
Accumulo包括一些有用的组合器开箱。要找到这些看看在org.apache.accumulo.core.iterators.user
包。
能够添加额外的合路,经过建立一个Java类,延长 org.apache.accumulo.core.iterators.Combiner的
加入一罐含有该类到Accumulo的lib / ext目录。
一个合成器的一个例子,能够发现
accumulo/examples/simple/main/java/org/apache/accumulo/examples/simple/combiner/StatsCombiner.java
为 了增长吞吐量的经常使用访问的条目,,采用了Accumulo块缓存。此块缓存缓冲区内存中的数据,所以,它并无被读出的磁盘。的RFile格式 Accumulo喜欢的组合索引块和数据块,索引块是用来寻找相应的数据块。典型的查询Accumulo结果在多个索引块的二进制搜索,而后经过线性扫描 的一个或多个数据块。
块缓存可配置每个表的基础上,在平板电脑上的服务器共享一个单一的资源池和全部药片托管。要配置tablet服务器的块高速缓存的大小,设置如下属性:
tserver.cache.data.size:指定的高速缓存文件的数据块的大小。 tserver.cache.index.size:指定文件索引的缓存的大小。
要启用的块缓存表,设置如下属性:
table.cache.block.enable:肯定是否启用文件(数据)块缓存。 table.cache.index.enable:肯定是否启用索引缓存。
块缓存能够有一个显着的效果,对缓解热点问题,以及减小查询延迟。它是默认启用的元数据表。
当 数据被写入到Accumulo缓存在内存中。缓冲在存储器中的数据最终被写入到HDFS上每片为基础。文件也能够直接向片批量导入。tablet服务器在 后台运行多个文件合并成一个主要的压实。tablet服务器来决定哪片紧凑,平板电脑内的文件压缩。做出这一决定是使用压缩率,这是每个表的基础上进行 配置。要配置这个比例修改下列属性:
table.compaction.major.ratio
增长这一比例将致使更多的文件每片和压实工做。更多文件每片意味着更高的查询延迟。所以,调整这个比例是一个权衡之间采集和查询性能。缺省值为3的比例。
的比率的工做方式是,一组文件被压缩到一个文件中,若是组中的文件的大小的总和是大于集合中的最大文件的大小的比值乘以。若是这是否是真正的平板电脑中的全部文件集,最大的文件被删除考虑,剩余的文件被认为是压实。这是重复,直到压实被触发或有考虑留下任何文件。
tablet服务器用来运行主要压实的后台线程的数量是可配置的。要配置此修改如下属性:
tserver.compaction.major.concurrent.max
此外,tablet服务器使用小型压实的线程数是可配置的。要配置此修改如下属性:
tserver.compaction.minor.concurrent.max
正在运行和排队的主要和次要的压实的数字可见的Accumulo显示器页面。这可让你看到,若是压实备份和上面的设置都须要调整。调整时可用的线程数,压实,考虑如地图和减小节点上运行的内核和其它任务的数量。
重 大压实若是没有跟上,那么的文件每片数将增加到一个点查询性能开始受到影响。来处理这种状况的一种方法是,以增长压缩比。例如,若是压缩比被设置为1,则 每个新的文件中添加一个平板轻微压实当即队列主要压实片剂。所以,若是平板电脑拥有一个200M的文件和小型压实写入一个1M的文件,那么主要的压实试 图合并200M和1M的文件。若是平板电脑服务器有不少片剂试图作这样的事情,那么主要的压实将备份和文件每片的数量将开始增加,假设数据被连续写入。增 加压实比例将缓解备份经过下降主要压实工做须要作。
另外一个选项来处理每片种植的文件太大调整如下属性:
table.file.max
当 平板电脑达到这个数字刷新其内存中的数据保存到磁盘文件和须要,它会选择作一个合并轻微压实。合并轻微压实,将平板电脑的最小文件合并轻微压缩时间在内存 中的数据。所以,文件的数量不会超过这个限制增加。这将使小压实须要更长的时间,这将致使摄取性能降低。这可能会致使摄取放慢主要压实,直到有足够的时间 遇上。当调整此属性,也考虑调整压缩率。理想的状况下,合并轻微的压实永远须要发生重大压实会跟上。配置文件最大和压实比只合并发生轻微压实和主要压实从 未发生,这是可能的。只由于这样作合并小压实致使O(Ñ 2)要作的工做,这应该被避免。主要压实完成的工做量是ø(N *日志ŗ(N)),其中 ŗ是压缩率。
一 个表能够手动进行压实。要启动一个小的压实,使用flush在shell命令。要发起一个重大的压实,使用外壳紧凑命令。紧凑的命令将压缩到一个文件中的 一个表中的全部片。即便同一个文件的平板电脑将被压缩。一个主要压实过滤器被配置为一个表的状况下,这是有用的。以1.4的压缩能力的范围内的一个表 中的溶液。要使用此功能指定启动中止紧凑命令行。这将只压缩片重叠在给定的行范围。
将平衡Accumulo跨服务器和分发表。表以前,变大时,它会保持在单个服务器上做为一个单一的片剂。这限制了在该数据能够被添加或查询的单个节点的速度的速度。为了提升性能,当一个表是新的,仍是小的,你能够添加分割点,产生新的平板电脑。
在shell:
root@myinstance> createtable newTable root@myinstance> addsplits -t newTable g n t
这将建立一个新的表4粒。该表将被分割的字母“G”,“N”,“T”,这将很好地工做,若是该行数据与小写字母字符开始。若是你的行数据包括二进制信息或数字信息,或者若是行信息的分布是不平坦的,那么你会选择不一样的分割点。如今采集和查询能够进行4个节点能够提升性能。
随 着时间的推移,一个表能够获得很是大,如此之大,它有数百成千上万的分割点。一旦有足够的片蔓延在整个集群中的一个表,额外的分裂可能不会提升性能,可能 会形成没必要要的簿记。数据的分布可能会随时间而改变。例如,若是行数据包含了最新的信息和数据的不断增长和删除,以维持目前的信息的一个窗口,为老年人行 的药片多是空的。
accumulo支持片剂合并,它能够被用来减小分割点的数目。下面的命令将全部行合并从“A”到“Z”成一个单一的平板电脑:
root@myinstance> merge -t myTable -s A -e Z
若是一个合并的结果产生一个大于配置的分割大小的片剂,片剂可能会被分割由数位板服务器。确定会增长平板电脑大小的任何合并前,若是咱们的目标是有较大的药片:
root@myinstance> config -t myTable -s table.split.threshold=2G
为了合并小药片,你能够问accumulo合并部分小于给定大小的表。
root@myinstance> merge -t myTable -s 100M
缺省状况下,小片将不会被合并到已经大于给定大小的片剂。这能够离开孤立的小药片。要强制合并成较大的片小药片使用“ - {} - force”选项:
root@myinstance> merge -t myTable -s 100M --force
合并分片上一节的时间。若是你的表中包含许多部分小分割点,或正在试图改变分割整个表的大小,这将是更快地分割点设置和合并整个表:
root@myinstance> config -t myTable -s table.split.threshold=256M root@myinstance> merge -t myTable
考虑索引方案使用最新的信息在每一行。例如“20110823-15:20:25.013的可能会对指定的日期和时间的行。在某些状况下,咱们可能会喜欢这个日期的基础上删除行说,删除全部的数据比当年旧。Accumulo支持删除操做,有效地消除两行之间的数据。例如:
root@myinstance> deleterange -t myTable -s 2010 -e 2011
这将删除全部以“2010”开始的行,它会停在“2011”开始的任何行。您能够删除任何数据,2011年以前:
root@myinstance> deleterange -t myTable -e 2011 --force
外壳不会容许你删除一个无限的范围内(不启动),除非你提供的“ - {} - force”选项。
范围的删除是经过使用在给定的开始/结束位置的分割,并且会影响在表中的分割的数目。
可 以建立一个新的表指向现有的表的数据。这是一个很是快的元数据操做,实际上没有数据复制。克隆表和源表能够改变独立后的克隆操做。这个功能的一个用例的测 试。例如,测试一个新的过滤迭代器,克隆表,添加过滤器的克隆,并迫使主要压实。要执行测试数据较少,克隆一个表,而后使用删除范围,有效地去除不少从克 隆的数据。另外一个用例生成一个快照,防范人为错误。要建立一个快照,克隆一个表,而后禁止克隆的写权限。
克隆操做将指向源表的文件。这就是为何flush选项默认状况下,在shell中存在并已启用。若是冲洗选项未启用,那么任何数据源表目前已在内存不存在克隆。
克隆表复制源表中的配置。然而,源表中的权限不会被复制到克隆。建立克隆后,只有用户建立克隆能够读取和写入。
在如下示例中,咱们能够看到,克隆操做以后插入的数据是不可见的克隆。
root@a14> createtable people root@a14 people> insert 890435 name last Doe root@a14 people> insert 890435 name first John root@a14 people> clonetable people test root@a14 people> insert 890436 name first Jane root@a14 people> insert 890436 name last Doe root@a14 people> scan 890435 name:first [] John 890435 name:last [] Doe 890436 name:first [] Jane 890436 name:last [] Doe root@a14 people> table test root@a14 test> scan 890435 name:first [] John 890435 name:last [] Doe root@a14 test>
du 命令在shell中显示一个表被使用在HDFS多少空间。此命令也能够显示在HDFS中有多少空间重叠的两个克隆表。在下面的例子都显示表CI是使用 428M。CI是克隆CIC和du代表这两个表共享428M。通过三个条目插入CIC和其满脸通红,都显示了这两个表仍然共享428M,但中投公司自己有 226个字节。最后,表CIC被压实,而后杜代表,每一个表使用428M。
root@a14> du ci 428,482,573 [ci] root@a14> clonetable ci cic root@a14> du ci cic 428,482,573 [ci, cic] root@a14> table cic root@a14 cic> insert r1 cf1 cq1 v1 root@a14 cic> insert r1 cf1 cq2 v2 root@a14 cic> insert r1 cf1 cq3 v3 root@a14 cic> flush -t cic -w 27 15:00:13,908 [shell.Shell] INFO : Flush of table cic completed. root@a14 cic> du ci cic 428,482,573 [ci, cic] 226 [cic] root@a14 cic> compact -t cic -w 27 15:00:35,871 [shell.Shell] INFO : Compacting table ... 27 15:03:03,303 [shell.Shell] INFO : Compaction of table cic completed for given range root@a14 cic> du ci cic 428,482,573 [ci] 428,482,612 [cic] root@a14 cic>
Accumulo 支持导出表的表复制到另外一个集群的目的。导出和导入表保留表配置,分裂,和逻辑的时间。表导出,而后复制经过的hadoop distcp命令。要导出表,它必须是离线和保持脱机而discp运行的。它须要保持脱机状态的缘由是为了防止文件被删除。表能够克隆和克隆脱机序,以避 免失去对表的访问。参见DOCS /例子/ README.export一个例子。
行 ID进行排序因为Accumulo表,每一个表均可以被认为是被索引的行ID。行ID进行查找,能够快速执行,作一个二进制搜索,第一个冲过片,而后在平板 电脑。客户应当心选择行ID,以支持其所需的应用程序。一个简单的规则是选择行ID为每一个实体的惟一标识符来存储和分配全部其余属性进行跟踪,根据此行的 ID列。例如,若是咱们有一个逗号分隔的文件中的下列数据:
userid,age,address,account-balance
咱们可能会选择此数据存储使用的的ROWID,其他列家庭中的数据的userid:
Mutation m = new Mutation(new Text(userid)); m.put(new Text("age"), age); m.put(new Text("address"), address); m.put(new Text("balance"), account_balance); writer.add(m);做家。(米);
经过指定的用户ID做为扫描仪的范围和获取特定的列,而后咱们就能够检索任何一个特定的用户ID列:
Range r = new Range(userid, userid); // single rowScanner s = conn.createScanner("userdata", auths); s.setRange(r); s.fetchColumnFamily(new Text("age"));for(Entry<Key,Value> entry : s) System.out.println(entry.getValue().toString());
一般,它是必要的,以便有预期的访问模式最适合的方式,是命令行变换ROWID。一个很好的例子,这是互联网域名的组成部分,以相同的父域组行的顺序颠倒过来:
com.google.code com.google.labs com.google.mail com.yahoo.mail com.yahoo.research
有些数据可能会致使在创造很是大的行 - 行有许多列。在这种状况下,表设计可能要拆分这些行更好的负载平衡,同时保持他们在一块儿排序的扫描目的。这能够经过在该行的末尾附加一个随机的子串:
com.google.code_00 com.google.code_01 com.google.code_02 com.google.labs_00 com.google.mail_00 com.google.mail_01
它也能够经过添加一个字符串表示的一段时间,如一周或一个月的日期:
com.google.code_201003 com.google.code_201004 com.google.code_201005 com.google.labs_201003 com.google.mail_201003 com.google.mail_201004
追加日期提供了一个给定的日期范围限制扫描的附加功能。
为 了支持经过查找一个实体的多个属性,额外的索引能够建。然而,由于Accumulo表能够支持任意数量的列不事先指定的一个附加指标每每会在主表中的记录 足以支持查找。在这里,该指数已为ROWID值或期限从主表,列的家庭都是同样的,预选赛的索引表列包含从主表的ROWID。
RowID | Column Family | Column Qualifier | Value |
---|---|---|---|
Term |
Field Name |
MainRowID |
注:咱们存储的rowid列预选赛,而不是价值,这样咱们就能够有一个以上的ROWID与一个特定的期限内的指数相关。若是咱们存储这个值,咱们只能看到一个值出现自Accumulo默认配置为返回一个最新的值与键关联的那些行。
而后,能够经过先扫描索引表出现须要的值在指定的列,返回一个列表,从主表行ID查找。这些能够被用于检索每一个匹配的记录,在他们的所有,或列的一个子集,从主表。
支 持高效查找多个从同一个表的rowid中,Accumulo客户端库提供一个BatchScanner。用户能够指定一组范围,在多个线程执行的查找到多 个服务器,并返回一个Iterator全部检索的行BatchScanner。返回的行排序顺序,不做为的状况下,基本的扫描仪接口。
// first we scan the index for IDs of rows matching our queryText term = new Text("mySearchTerm");HashSet<Text> matchingRows = new HashSet<Text>();Scanner indexScanner = createScanner("index", auths); indexScanner.setRange(new Range(term, term));// we retrieve the matching rowIDs and create a set of rangesfor(Entry<Key,Value> entry : indexScanner) matchingRows.add(new Text(entry.getKey().getColumnQualifier()));// now we pass the set of rowIDs to the batch scanner to retrieve themBatchScanner bscan = conn.createBatchScanner("table", auths, 10); bscan.setRanges(matchingRows); bscan.fetchFamily("attributes");for(Entry<Key,Value> entry : scan) System.out.println(entry.getValue());
动 态模式的Accumulo能力的优势之一是,不一样的字段能够采集到同一物理表。可是,它可能有必要创建不一样的索引表,若是不一样的条款必须进行格式化, 以保持适当的排序顺序。例如,实数必须比本身平时的符号不一样的格式,以正确排序。在这些状况下,一般独特的数据类型的每个索引就足够了。
Accumulo是理想的存储实体及其属性的属性,特别是稀疏。它每每是一块儿加入多个数据集,在同一表常见的实体。这能够容许的表明性的曲线图,其中包括节点,它们的属性,而且它链接到其余节点。
存储个别事件,而非实体的属性或图形表存储聚合信息的事件中所涉及的实体和实体之间的关系。单一事件时,不是很是有用,当随意一个不断更新的聚合,这一般是可取的。
实体 - 属性或图形表的物理架构以下:
RowID | Column Family | Column Qualifier | Value |
---|---|---|---|
EntityID |
Attribute Name |
Attribute Value |
Weight |
EntityID |
Edge Type |
Related EntityID |
Weight |
例如,要跟踪员工,经理和产品如下实体属性表可使用。注意所用的权并不老是必要的,被设置为0时,不使用。
RowID | Column Family | Column Qualifier | Value |
---|---|---|---|
E001 |
name |
bob |
0 |
E001 |
department |
sales |
0 |
E001 |
hire_date |
20030102 |
0 |
E001 |
units_sold |
P001 |
780 |
E002 |
name |
george |
0 |
E002 |
department |
sales |
0 |
E002 |
manager_of |
E001 |
0 |
E002 |
manager_of |
E003 |
0 |
E003 |
name |
harry |
0 |
E003 |
department |
accounts_recv |
0 |
E003 |
hire_date |
20000405 |
0 |
E003 |
units_sold |
P002 |
566 |
E003 |
units_sold |
P001 |
232 |
P001 |
product_name |
nike_airs |
0 |
P001 |
product_type |
shoe |
0 |
P001 |
in_stock |
germany |
900 |
P001 |
in_stock |
brazil |
200 |
P002 |
product_name |
basic_jacket |
0 |
P002 |
product_type |
clothing |
0 |
P002 |
in_stock |
usa |
3454 |
P002 |
in_stock |
germany |
700 |
为了有效更新的边权重,合计迭代器能够配置相同的密钥应用的全部突变添加值。这些类型的表能够很容易地建立从原始事件,个别事件的实体,属性和关系经过简单的提取和插入钥匙进入Accumulo各计数1。聚合迭代会照顾保持边缘权重。
用一个简单的索引如上所述运做良好时,寻找匹配的记录一组给定的标准之一。同时符合多个条件的记录,如寻找文件包含全部的话时,当寻找'和'白'和'家',有几个问题。
首先是必须被发送到客户端,这会致使网络流量的特定匹配的搜索条件中的任一项,该组的全部记录。第二个问题是客户端是负责执行的交集上套的记录返回,以消除全部,但全部搜索条件匹配的记录。内存的客户端可能会在此操做过程当中很容易被淹没。
因为这些缘由,Accumulo包括支持的方案被称为分片索引,这些组操做能够被执行上面的TabletServers决定哪些记录包括在结果集中的,能够在不产生网络流量。
这是经过分割记录成箱,每一个驻留在至多一个TabletServer上,而后建立一个索引,每一个记录在每一个垃圾桶以下:
RowID | Column Family | Column Qualifier | Value |
---|---|---|---|
BinID |
Term |
DocID |
Weight |
由 用户定义的摄取应用映射到文件或记录。存储BinID的ROWID,咱们确保特定斌的全部信息都包含在一个单一的平板电脑,并托管在一个单一的 TabletServer以来从未分裂Accumulo行跨片。存储列家庭服务条款,使在这个垃圾桶的全部文件包含给定的长期快速查找。
最 后,咱们进行交集操做,经过一个特殊的迭代器称为相交迭代TabletServer。因为文件分割成许多垃圾桶,搜索全部文件必须搜索每个垃圾桶。咱们 可使用BatchScanner,并行扫描全部的垃圾桶。相交迭代器应该启用一个BatchScanner在用户查询代码以下:
Text[] terms = {new Text("the"), new Text("white"), new Text("house")};BatchScanner bs = conn.createBatchScanner(table, auths, 20);IteratorSetting iter = new IteratorSetting(20, "ii", IntersectingIterator.class); IntersectingIterator.setColumnFamilies(iter, terms); bs.addScanIterator(iter); bs.setRanges(Collections.singleton(new Range()));for(Entry<Key,Value> entry : bs) { System.out.println(" " + entry.getKey().getColumnQualifier()); }
此 代码有效的BatchScanner扫描一个表的全部平板电脑,寻找符合全部条款的文件。由于全部的平板电脑正在扫描的每一个查询,每一个查询比其余的 Accumulo扫描,这一般涉及少数TabletServers更加昂贵。这减小了支持的并发查询数量和被称为'掉队'的问题,其中每个查询运行慢最 慢的服务器参与。
固然,快速的服务器将其结果返回给客户端,它能够显示给用户,而他们等待的结果到达其他当即。若是结果是无序的,这是一个至关有效的到达第一的成绩不如其余任何用户。
accumulo常常被用来做为一个更大的数据处理和存储系统的一部分。涉及Accumulo,摄取和查询组件的并行系统性能发挥到极致的设计应提供足够的并行和并发性,以免产生瓶颈,为用户和其余系统写入和读取Accumulo。有几种方法,以实现高接收性能。
新表包括默认状况下,一个单一的平板电脑。因为基因突变,表的增加和分裂成平衡由主跨TabletServers的多个片。这意味着总的摄取率将被限制在更少的服务器为群集内的,直到表中已经到了有是在每一个TabletServer片其中。
预分割表,确保有尽量多片随意摄取前开始利用一切可能的并行集群硬件。表能够随时拆分使用shell:
user@myinstance mytable> addsplits -sf /local_splitfile -t mytable
就提供并行摄取的目的,没有必要创造更多的平板电脑比有物理机集群内合共摄取率是一个函数的物理机数量。请注意,合共摄取率仍然摄取客户的机器上运行的数量,分布的rowid桌子对面的。的汇集摄取率将是次优的,若是有许多插入一个小数目的rowid。
Accumulo 是可以扩展的摄取率很是高,这是取决于有多少人TabletServers运转中,但也摄取客户的数量。这是由于单个客户端,同时能配料突变和将它们发送 到全部TabletServers,是最终在一台机器能够处理的数据的量限制。合共摄取率的客户端数点在其中的总I / O的TabletServers或总的网络带宽容量达到线性扩展。
在高利率的摄取是最重要的操做设置,群集一般配置仅运行Ingester客户奉献必定数量的机器。客户最佳的摄食率必要TabletServers,精确的比率会有所不一样,根据每台机器的资源和数据类型的分布。
Accumulo 支持的能力,如MapReduce的外部进程所产生的文件导入到现有的表。在某些状况下,它可能会更快加载数据,这种方式经过经过客户使用 BatchWriters摄入而非。这使得大量的机器格式化数据的方式Accumulo预期。的新文件,而后简单地介绍到Accumulo经过一个 shell命令。
要 配置的MapReduce准备批量加载数据格式化,做业应设置使用范围分区工具,而不是默认的哈希分区工具。范围分区工具使用分割点的Accumulo 表,将接收到的数据。分割点,可从外壳由MapReduce RangePartitioner的使用。请注意,这仅仅是有用的,若是现有的表已经分裂成多个片。
user@myinstance mytable> getsplits aa ab ac ... zx zy zz
运行MapReduce做业,使用建立文件的AccumuloFileOutputFormat被介绍给Accumulo的。一旦完成,文件能够添加到Accumulo经过壳:
user@myinstance mytable> importdirectory /files_dir /failures
须要注意的是引用的路径是目录,Accumulo运行在同一个HDFS实例。Accumulo将没有任何文件被添加到指定的第二个目录。
一个完整的例子,能够发如今使用大量摄取 accumulo /文档/例子/ README.bulkIngest
逻 辑的时间是很是重要的大宗进口数据,客户端代码可能会选择一个时间戳。在批量导入时,用户能够选择被导入文件的集合时间,以使逻辑。当它的启 用,Accumulo使用迭代次批量导入的文件中懒洋洋地设置一个专门的系统。这种机制确保了时间不一样步多节点应用程序(如运行MapReduce的)将 保持必定的因果顺序的假象。这减轻了问题的时间是错误的系统上建立该文件批量导入。导入该文件时,这些时间都没有设置,但只要它是读取扫描或压实。进口, 在一段时间内得到和老是使用由专门的系统迭代设置时间。
的时间戳分配的accumulo将在该文件中的每个键是相同的。这可能会致使问题,若是文件中包含多个密钥是相同的时间戳除外。在这种状况下,按键的排序顺序是不肯定的。这可能发生,若是在同一批量导入文件插入和更新。
这 是可能的,以有效地写入许多突变Accumulo的平行的方式从一个MapReduce做业。在这种状况下被写入MapReduce的数据处理,住在 HDFS中,写突变Accumulo使用AccumuloOutputFormat的。见的MapReduce下节分析的详细信息。
使用MapReduce的一个例子能够找到根据accumulo/docs/examples/README.mapred
Accumulo支持更先进的数据处理不是简单的保持按键的排序和执行高效的查找。Google Analytics(分析)能够开发使用MapReduce和配合Accumulo表中的迭代器。
Accumulo 表能够做为MapReduce做业的源和目标。与MapReduce做业要使用Accumulo的表(特别是新的Hadoop的API版本0.20),做 业参数配置,使用AccumuloInputFormat AccumuloOutputFormat。经过这两种格式类Accumulo具体参数能够设置,作到如下几点:
输入验证并提供用户凭据
限制扫描必定范围的行
限制输入可用列的一个子集
要阅读从Accumulo表与下面的类的参数,并建立一个映射请务必配置AccumuloInputFormat的。
class MyMapper extends Mapper<Key,Value,WritableComparable,Writable> { public void map(Key k, Value v, Context c) { // transform key and value data here } }
要 写入一个Accumulo表,与下面的类的参数,并建立一个减速请务必配置AccumuloOutputFormat的。从减速机发射的关键标识被发送到 的表的突变。这容许一个单一的减速写信给一个以上的表,若是须要的。一个默认的表可使用AccumuloOutputFormat配置,在这种状况下, 在输出表的名称没有被传递到减速机内的上下文对象。
class MyReducer extends Reducer<WritableComparable, Writable, Text, Mutation> { public void reduce(WritableComparable key, Iterable<Text> values, Context c) { Mutation m; // create the mutation based on input key and value c.write(new Text("output-table"), m); } }
经过为输出文本对象应包含表的名称应采用这种突变。文本能够是空的,在这种状况下,突变将被应用到默认指定表名在AccumuloOutputFormat股权。
Job job = new Job(getConf()); AccumuloInputFormat.setInputInfo(job, "user", "passwd".getBytes(), "table", new Authorizations()); AccumuloInputFormat.setZooKeeperInstance(job, "myinstance", "zooserver-one,zooserver-two");
可选设置:
Accumulo限制到一组行范围:
ArrayList<Range> ranges = new ArrayList<Range>();// populate array list of row ranges ...AccumuloInputFormat.setRanges(job, ranges);
accumulo限制到一个列表的列:
ArrayList<Pair<Text,Text>> columns = new ArrayList<Pair<Text,Text>>();// populate list of columnsAccumuloInputFormat.fetchColumns(job, columns);
使用正则表达式来匹配行IDs:
AccumuloInputFormat.setRegex(job, RegexType.ROW, "^.*");
boolean createTables = true;String defaultTable = "mytable"; AccumuloOutputFormat.setOutputInfo(job, "user", "passwd".getBytes(), createTables, defaultTable); AccumuloOutputFormat.setZooKeeperInstance(job, "myinstance", "zooserver-one,zooserver-two");
可选设置:
AccumuloOutputFormat.setMaxLatency(job, 300); // millisecondsAccumuloOutputFormat.setMaxMutationBufferSize(job, 5000000); // bytes
一个示例使用MapReduce和Accumulo能够发现accumulo/docs/examples/README.mapred
d
许多应用程序均可以从中受益的能力,总价值跨越经常使用键。这是能够作到经过合路器的迭代器,和相似的减小MapReduce的步骤。这提供了定义在线增量更新的分析能力,没有面向批处理的MapReduce做业相关的开销或延迟。
全部这一切都须要一个表的总价值来识别字段值将被分组,插入突变与这些领域的关键,组合迭代器支持所需的总结操做和配置表。
结合迭代的惟一限制是,组合开发人员不该该承担全部的值给定键已经看到,因为新的突变能够随时插入。这排除了如计算平均值时,例如在聚合中使用的值的总数。
相 结合的迭代器范围内Accumulo的表的一个有趣的用途是存储用于在机器学习算法的特征矢量。例如,许多算法,如k-means聚类,支持向量机,异常 检测等使用特征向量的概念和计算距离度量学习一个特定的模式。可用于列中一个Accumulo表中有效地存储稀疏特征和他们的重量,以经过使用一个组合的 迭代器进行增量更新。
须要更新,由多台机器上并行的统计模型,能够相似地存储范围内Accumulo表。例如,能够有一个MapReduce的工做是一个全球性的统计模型迭代更新每一个地图,或下降了工做人员的工做参考经过一个嵌入式Accumulo的客户端被读取和更新的模型零件的。
使用Accumulo这样小块的信息,在随机存取模式,这是相辅相成的MapReduce的顺序访问模式实现高效,快速的查找和更新。
Accumulo 延伸BigTable的数据模型来实现的安全机制被称为单元级别的安全。每个键 - 值对都有本身的安全标签,存储的密钥,该密钥是用来肯定一个给定的用户是否知足安全要求的值读列下的可见性元素。这使得数据被存储在同一行内的多种安全级 别,以及不一样程度的访问相同的表查询的用户,同时保持数据的机密性。
当突变的应用,用户能够指定一个安全标签的每一个值。这样作是经过一个ColumnVisibility对象的put()方法建立的突变:
Text rowID = new Text("row1");Text colFam = new Text("myColFam");Text colQual = new Text("myColQual");ColumnVisibility colVis = new ColumnVisibility("public");long timestamp = System.currentTimeMillis();Value value = new Value("myValue");Mutation mutation = new Mutation(rowID); mutation.put(colFam, colQual, colVis, timestamp, value);
防伪标签由一组所须要的值读标签是与用户定义的令牌。能够指定所需的令牌的集合,支持的令牌的逻辑“与”和“或”的组合,以及嵌套组的令牌一块儿使用的语法。
例如,假设在咱们的组织,咱们但愿咱们的数据值标签防伪标签用户角色定义。咱们可能已经令牌,如:
管理员 审计 系统
这些能够单独指定,或结合使用逻辑运算符:
/ /用户必须具备管理员权限: 管理员
/ /用户必须具备管理员和审核权限 管理审计
/ / admin或审计权限的用户 管理|审计
/ /用户必须具备审计和管理员或系统中的一个或两个 (管理系统)及审计
当|
与
运营商的使用,必须使用括号来指定优先级的运算符。
当客户端试图读取数据从Accumulo,任何防伪标签进行检查对集时扫描仪或BatchScanner的建立经过客户端代码的受权。若是受权被肯定为不足,以知足安全标签,该值被抑制结果发送回给客户端的一组。
指定受权用户拥有令牌做为一个逗号分隔的列表:
// user possesses both admin and system level accessAuthorization auths = new Authorization("admin","system");Scanner s = connector.createScanner("table", auths);
每一个accumulo用户具备一组相关联的安全性标签。要操纵这些在shell中使用setuaths和getauths命令。这些也可使用java安全操做API修改。
当用户建立了一个扫描仪,经过一组受权。若是传递到扫描仪的受权用户受权的一个子集,而后将抛出一个异常。
为了防止用户写他们没法读取数据,添加的知名度约束到表中。使用EVC选项的CREATETABLE shell命令启用此约束。对于现有的表使用下面的shell命令到启用的知名度约束。确保约束不与任何现有的约束冲突。
config -t table -s table.constraint.1=org.apache.accumulo.core.security.VisibilityConstraint
ALTER TABLE权限的任何用户能够添加或删除此约束。此约束并不适用于大容量导入数据,若是这是一个关注,而后禁用批量的进口许可。
对 于许多用户提供服务的应用程序,它并不指望将建立一个accumulo用户,每一个应用程序用户。在这种状况下,任何的应用程序的用户所须要的全部受权的 accumulo用户必须被建立。服务查询,应用程序应该建立一个扫描仪应用程序用户的受权。这些受权能够获得可信的第三方。
生 产系统一般将整合公共密钥基础设施(PKI)和指定的客户端代码在查询使用PKI服务器层进行谈判,以验证用户身份并获取受权令牌(凭据)。这要求用户指 定所必需的信息,来验证本身的系统。用户身份一旦创建,他们的凭据能够访问客户端代码及用户之所及以外传递给Accumulo,。
由 于的主要方法的互动与Accumulo是经过Java API,生产环境中常常调用的执行查询层。这能够经过在容器中使用Web服务的Apache Tomcat这样的,但不是必需的。查询服务层提供面向用户的应用程序能够创建一个平台,提供了一种机制。这容许应用程序设计者隔离潜在的复杂的查询逻 辑,并执行基本的安全功能提供了一种方便点。
一些生产环境,选择在这一层,用户标识符用于检索的访问凭据,而后缓存在查询层,并提交到Accumulo经过受权机制来实现认证。
一般状况下,查询服务层位于在Accumulo和用户工做站之间。
由于咱们正在运行的基本上是两个或三个同时整个集群分层系统:HDFS,Accumulo和MapReduce,这是典型的由4至8核心,8到32 GB RAM的硬件。这是这样每一个正在运行的过程当中能够有至少一个芯和2 - 4 GB的。
运行HDFS的核心之一,一般能够保持2至4个磁盘忙,因此每台机器可能一般为2×300GB硬盘和多达4个1TB或2TB磁盘。
低 于这一标准,如与1U服务器2芯和4GB每一个是能够作到的,但在这种状况下,建议只运行每台机器上的两个过程 - 即的DataNode和TabletServer的或的DataNode和MapReduce的工人,但不全部三个。这里的约束是有足够的可用堆空间,一 台机器上的全部进程。
Accumulo经过远程过程调用两个传递数据和控制信息经过TCP / IP进行通讯。此外,Accumulo使用HDFS客户沟通与HDFS。为了达到良好的采集和查询性能,足够的网络带宽必须可任意两台机器之间。
选择目录安装Accumulo。这个目录将被引用环境变量$ ACCUMULO_HOME
。运行如下命令:
$ tar xzf accumulo-assemble-1.5.0-bin.tar.gz # unpack to subdirectory $ mv accumulo-assemble-1.5.0-bin $ACCUMULO_HOME # move to desired location
在群集内的每台机器重复此步骤。一般状况下,全部的机器有相同的$ ACCUMULO_HOME
。
Accumulo 须要HDFS,ZooKeeper的配置和运行开始以前。密码应配置SSH至少Accumulo主和TabletServer机之间。在集群中运行网络时 间协议(NTP),以确保节点的时钟,不要太脱节,这可能会致使自动时间戳数据的问题,这也是一个不错的主意。
Accumulo配置编辑几个壳牌和XML文件中发现 $ ACCUMULO_HOME / conf目录
。其结构相似于Hadoop的配置文件。
Accumulo须要知道在哪里能够找到它依赖于软件。编辑accumulo env.sh指定如下内容:
输入的安装目录Accumulo为ACCUMULO_HOME美圆
的位置
输入您系统的Java回家$ JAVA_HOME
Hadoop的输入位置为$ HADOOP_HOME
选择的位置Accumulo日志,并将其输入$ ACCUMULO_LOG_DIR“
输入的ZooKeeper为ZOOKEEPER_HOME美圆
的位置
经过默认Accumulo TabletServers被设置为使用1GB的内存。你可能会改变这个经过改变价值$ ACCUMULO_TSERVER_OPTS
。注意语法是Java的JVM命令行选项。此值应小于物理内存的运行TabletServers机器。
有主人的内存使用和垃圾收集过程当中的相似选项。若是他们超出物理RAM的硬件,减小这些,增长他们的物理RAM的范围内,若是一个进程失败,由于内存不足。
请 注意,您将指定Java堆空间,在accumulo env.sh。您应确保总的堆空间用于Accumulo TSERVER和在Hadoop的DataNode和TaskTracker必须是小于集群中的每一个从节点上的可用内存。大型集群上,建议,均可以在不一样 的机器上运行Hadoop的NameNode的Accumulo主,次要的NameNode,和Hadoop JobTracker的容许他们使用更多的堆空间。若是您运行的是一小簇在同一台机器上,一样确保他们的堆空间设置适合于可用的内存。
在机器将做为的Accumulo主:
写$ ACCUMULO_HOME / conf目录/硕士
文件Accumulo主的IP地址或域名。
写的机器,这将是在$ ACCUMULO_HOME / conf目录/奴隶
,每行一个TabletServers的IP地址或域名。
请注意,若是使用域名而不是IP地址,DNS必须配置正确参与集群中的全部机器。DNS能够是一个混乱的错误源。
指定适当的值ACCUMULO_HOME元/ conf目录/ accumulo的site.xml
中的下列设置:
<property> <name>zookeeper</name> <value>zooserver-one:2181,zooserver-two:2181</value> <description>list of zookeeper servers</description></property>
这使找到的ZooKeeper Accumulo。Accumulo使用ZooKeeper的协调过程,并有助于敲定TabletServer失败之间设置的。
<property> <name>walog</name> <value>/var/accumulo/walogs</value> <description>local directory for write ahead logs</description></property>
Accumulo预写日志记录全部变动表,而后将它们提交到表。“walog设置指定预写日志写入到每台机器上的本地目录。这个目录应该存在全部机器上做为TabletServers的。
<property> <name>instance.secret</name> <value>DEFAULT</value></property>
实例须要一个秘密,使服务器之间的安全通讯。配置你的秘密,并确保不向其余用户可读,的site.xml accumulo的
文件是。
能够修改某些设置经过Accumulo外壳,并当即生效,但一些设置须要一个过程从新启动才能生效。有关详细信息,请参阅“配置文件(可在监视器上的网页)。
复制的主人,奴隶,env.sh accumulo,若是有必要,accumulo的site.xml从$ ACCUMULO_HOME / conf目录/
全部的机器的奴隶文件中指定主目录。
必须初始化Accumulo建立的结构,它在内部使用定位数据在集群。HDFS是必需要配置和运行以前Accumulo能够初始化。
HDFS开始后,能够进行初始化经过执行 $ ACCUMULO_HOME /bin/ accumulo的初始化
。这个脚本会提示输入名称此实例Accumulo。实例名称是用来肯定一套表和特定于实例的设置。而后,该脚本将一些信息写入到HDFS,因此Accumulo能够正常启动。
初始化脚本会提示你设置root密码。一旦Accumulo初始化后,就能够开始。
确保上配置的Hadoop集群中的全部机器,包括访问共享HDFS实例。确保HDFS,ZooKeeper的运行。请确保ZooKeeper的配置和集群中的至少一台计算机上运行。启动Accumulo使用BIN /
start-all.sh
脚本。
为了验证,运行Accumulo,检查“状态”页面监控下 。此外,shell可提供一些信息表经过读取元数据表的状态。
要正常关机,运行的BIN /stop-all.sh
和主协调全部的tablet服务器关机。的关机等待完成全部的小压实,因此它可能须要一些时间为特定的配置。
主Accumulo监测的Accumulo组件的状态和健康提供了一个接口。这个接口能够访问指着Web浏览器http://accumulomaster:50095/status
Accumulo处理每写一组日志文件。默认状况下,这些被发现下 $ ACCUMULO /logs/
。
关闭Accumulo TabletServer故障或错误的状况下,有些突变可能不会一直未成年人正确压缩到HDFS。在这种状况下,将自动从新Accumulo这种突变的预写日志时,片从故障服务器从新分配由主,在一个单一的TabletServer故障的状况下,或下一次启动Accumulo,在发生故障时,关机期间。
要求预写日志记录器复制到HDFS进行恢复。复制日志,他们还整理,使平板电脑能够很容易地找到他们失踪的更新。在Accumulo监控状态页显示每一个文件的复制/排序状态。一旦恢复完成涉及任何片应回到``在线“状态,到那时,这些药片将没法给客户。
Accumulo客户端库配置重试失败的突变,并在许多状况下,客户将可以继续处理后的恢复过程当中,没有抛出任何异常。