结尾为什么ios 添加全局断点唯一的fileid

君,已阅读到文档的结尾了呢~~
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
分布式存储系统设计与实现.pdf
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口java基础(6)
转载出处。
局唯一ID生成器浅析
我们在开发中,有时非常需要一个全局唯一的ID值,不管是业务需求,还是为了以后可能的分表需求,全局唯一值都非常有用,本篇大象就来讲讲这个实现并对ID生成器性能进行一下测试。
大象所讲的这个全局唯一ID生成器,其实是Twitter公开的一个算法,源码是用Scala写的,被国内的开源爱好者改写成了Java版本。
大象将这个类的调用简化了一下,实际使用中还是应该根据机器节点和数据中心节点来配置相关的参数。我这里假设只有一个节点作为ID号的生成器,所以workerId和datacenterId都设为0,当前时间与计算标记时间twepoch(Thu, 04 Nov :54 GMT)之间的毫秒数是一个38位长度的long值,再左移timestampLeftShift(22位),就得到一个60位长度的long数字,该数字与datacenterId && datacenterIdShift取或,datacenterId最小值为0,最大值为31,所以长度为1-5位,datacenterIdShift是17位,所以结果就是最小值为0,最大值为22位长度的long,同理,workerId && workerIdShift的最大值为17位的long。所以最终生成的会是一个60位长度的long型唯一ID
* 全局唯一ID生成器
public class IdGen {
private long workerId;
private long datacenterId;
private long sequence = 0L;
private long twepoch = 7L;
private long workerIdBits = 5L;
private long datacenterIdBits = 5L;
private long maxWorkerId = -1L ^ (-1L && workerIdBits);
private long maxDatacenterId = -1L ^ (-1L && datacenterIdBits);
private long sequenceBits = 12L;
private long workerIdShift = sequenceB
private long datacenterIdShift = sequenceBits + workerIdB
private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdB
private long sequenceMask = -1L ^ (-1L && sequenceBits);
private long lastTimestamp = -1L;
private static class IdGenHolder {
private static final IdGen instance = new IdGen();
public static IdGen get(){
return IdGenHolder.
public IdGen() {
this(0L, 0L);
public IdGen(long workerId, long datacenterId) {
if (workerId & maxWorkerId || workerId & 0) {
throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
if (datacenterId & maxDatacenterId || datacenterId & 0) {
throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
this.workerId = workerId;
this.datacenterId = datacenterId;
public synchronized long nextId() {
long timestamp = timeGen();
if (timestamp & lastTimestamp) {
throw new RuntimeException(String.format(
"Clock moved backwards.
Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
if (lastTimestamp == timestamp) {
sequence = (sequence + 1) & sequenceM
if (sequence == 0) {
timestamp = tilNextMillis(lastTimestamp);
sequence = 0L;
lastTimestamp =
return ((timestamp - twepoch) && timestampLeftShift) | (datacenterId && datacenterIdShift)
| (workerId && workerIdShift) |
protected long tilNextMillis(long lastTimestamp) {
long timestamp = timeGen();
while (timestamp &= lastTimestamp) {
timestamp = timeGen();
protected long timeGen() {
return System.currentTimeMillis();
final IdGen idGen = IdGen.get();
------接下来我再写个测试类,看下并发情况下,1秒钟可以生成多少个ID。我测试用的电脑CPU为I5-4210U,内存8G,JDK为1.7.0_79,系统是64位WIN 7,使用-server模式。
import java.util.ArrayL
import java.util.L
import java.util.concurrent.C
import java.util.concurrent.ExecutorS
import java.util.concurrent.E
import java.util.concurrent.TimeU
import org.junit.T
public class GeneratorTest {
public void testIdGenerator() {
long avg = 0;
for (int k = 0; k & 10; k++) {
List&Callable&Long&& partitions = new ArrayList&Callable&Long&&();
final IdGen idGen = IdGen.get();
for (int i = 0; i & 1400000; i++) {
partitions.add(new Callable&Long&() {
public Long call() throws Exception {
return idGen.nextId();
ExecutorService executorPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
long s = System.currentTimeMillis();
executorPool.invokeAll(partitions, 10000, TimeUnit.SECONDS);
long s_avg = System.currentTimeMillis() -
System.out.println("完成时间需要: " + s_avg / 1.0e3 + "秒");
executorPool.shutdown();
} catch (Exception e) {
e.printStackTrace();
System.out.println("平均完成时间需要: " + avg / 10 / 1.0e3 + "秒");
运行10次,平均下来,每次1.038秒生成140万个ID,除了第1次时间在3秒左右和第2次1.6秒左右,其余8次都在0.7秒左右。如果使用更好的硬件,测试数据肯定会更好。因此从大的方向上看,单节点的ID生成器基本上可以满足我们的需要了。
需要注意的是,该值只是一个唯一值,但并不能保证会是一个顺序值,就是说两个ID之间可能会跳一些数字,所以对于一些有特殊需求的业务来说请注意这个差异。
本文为菠萝大象原创,如要转载出处。http://www.blogjava.net/bolo
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:4377次
排名:千里之外
原创:12篇
转载:45篇
(9)(14)(16)(19)
(window.slotbydup = window.slotbydup || []).push({
id: '4740887',
container: s,
size: '250,250',
display: 'inlay-fix'520.EPOST是如何表示邮件文件夹的,POS;suchasthenumberofIProuti;spacecannolongercommunic;息来完成的;Application)和route(msg,k;thePastrynodewiththeproc;thatareclosest(according;set.539.Pastry将消息送到数值上最接
520. EPOST是如何表示邮件文件夹的,POST中的log是什么意思,它如何能表示文件夹? 521. 邮件的发送和接收是如何完成的? 522. 邮件的安全措施是怎样的? 523. 邮件的帐户是如何申请和分配的?域名是什么? 524. EPOST和老的邮件系统之间的接口是如何实现的? 525. EPOST的邮件格式是怎样的? 526. EPOST应用是如何配置的?当前用户的帐户如何填写上去? 527. 用EPOST的好处是什么?坏处是什么? 528. 哈希表中的碰撞如何处理? 529. POST的log是怎么回事? 530. Each mail folder is represented by an encrypted POST log. 531. Pastry’s notion of network proximity is based on a scalar proximity metric, such as the number of IP routing hops or geographic distance. 532. A Pastry node is considered failed when its immediate neighbors in the nodeId space can no longer communicate with the node. 533. Pastry的结点加入和退出就像互联网中路由器的加入和退出一样,是通过互发消息来完成的。 534. 自组织Self-Organization指结点的加入和退出。 535. Pastry给上层应用程序提供的接口有nodeId = pastryInit(Credentials, Application)和route(msg,key),而应用程序也有提供给Pastry回调的函数包括:deliver(msg,key)、forward(msg,key,nextId)、newLeafs(leafSet) 536. The application argument is a handle to the application object that provides the Pastry node with the procedures to invoke when certain events happen, e.g., a message arrival. 537. The neighborhood set M contains the nodeIds and IP addresses of the M nodes that are closest (according the proximity metric) to the local node. The neighborhood set is not normally used it is useful in maintaining locality properties,as discussed in Section 2.5. The leaf set L is the set of nodes with the L/2 numerically closest larger nodeIds, and the L/2 nodes with numerically closest smaller nodeIds,relative to the present node’s nodeId. The leaf set is used during the message routing. 538. Each Pastry node maintains a routing table, a neighborhood set and a leaf set. 539. Pastry 将消息送到数值上最接近fileId的NodeId中。This is accomplished as follows. In each routing step, a node normally forwards the message to a node whose nodeId shares with the key a prefix that is at leastone digit (or b bits) longer than the prefix that the key shares with the present node’sid. If no such node is known, the message is forwarded to a node whose nodeId shares a prefix with the key as long as the current node, but is numerically closer to the key than the present node’s id. 540. NodeId是通过Hash函数根据IP地址随机生成的, IP地址和NodeId有一一对应关系。 541. A Pastry system is a self-organizing overlay network of nodes, where each node routes client requests and interacts with local instances of one or more applications. 542. scalability:可伸缩性、可扩展性 543. 杭州网也有英文版 544. Endpoint.java―This interface represents an endpoint which applications can use to send messages from. An endpoint is obtained by the registerApplication() method in Node. The endpoint represents the applications' view of the world. 545. bootstrap: 引导程序,引导指令 546. Daemon thread ― Prevents the JVM from exiting after the main method is complete. 547. PastryNode ― This is a Node in the network. Your application will send messages through the node and the node will deliver messages to your application. 548. ANT的安装解包后在系统可执行路径中加入指向ant的bin的路径就可以了。 549. ant最适合你使用UltraEdit(EditPlus)写java程序,然后你使用ant去编译 550. ant是一个基于JAVA的自动化脚本引擎,脚本格式为XML。除了做JAVA编译相关任务外,ANT还可以通过插件实现很多应用的调用。每个ant脚本(缺省叫build.xml)中设置了一系列任务(target):比如对于一个一般的项目可能需要有以下任务。 任务1:usage 打印本脚本的帮助信息(缺省)
任务2:clean <-- init 清空初始化环境
任务3:javadoc <-- build <-- init 生成JAVADOC
任务4:jar <-- build <-- init 生成JAR
任务5:all <-- jar + javadoc <-- build <-- init 完成以上所有任务:jar javadoc 而多个任务之间往往又包含了一定了依赖关系:比如把整个应用打包任务(jar)的这个依赖于编译任务(build),而编译任务又依赖于整个环境初始化任务(init)等。 551. 现在在C#中本身提供了连接池,这样我们在取得DataTable后调用Close方法实际上没有关闭连接,本来应该在记录集使用完毕后才能关闭,而不是在取得记录集后马上关闭,现在单用户是没有问题,如果是多用户并发,一个用户close后把连接返回给连接池,马上被另一个用户拿去使用,这样记录集还打开着,会不会有问题? 552. 图书馆网站上有很多论文好好看。中国期刊网、IEEE、万方数据库。 553. PAST是微软公司联合Rice University开发的一个大规模P2P存储系统。所有加入PAST系统的结点在Pastry路由算法的组织下形成一个结构化分布的P2P Overlay网络。Pastry为每个文件分配全局唯一的文件标识fileId,并为每个结点分配一个唯一的nodeId。通过这个标识,系统中的结点组成一个环形的拓扑结构。 三亿文库包含各类专业文献、行业资料、外语学习资料、各类资格考试、生活休闲娱乐、文学作品欣赏、应用写作文书、中学教育、EPOST学习记录71等内容。 
 HTTP中Get、Post学习摘要总结_计算机软件及应用_IT/计算机_专业资料。HTTP 中 ...(2)其他人查看浏览器的历史纪录,那么别人就可以 拿到你的账号和密码了,除此...  PM POST学习心得_学习总结_总结/汇报_实用文档。powermilii 五轴后置修改教程 PM POST 学习心得最近狂研究 PM 当然任何一个做 NC 的人, 对 POST 的更改都是...  post英语报文章集锦_英语学习_外语学习_教育专区。说起这几年流行的包包, “剑桥包”首当其冲!你知道它的由来吗? A famous fashion brand Cambridge satchels (...  Post Structuralism Ch 12_英语学习_外语学习_教育专区。Dunne, Kurki & Smith: International Relations Theories 3e Chapter 12 ? Every understanding of inteDunne...  有道Post_英语学习_外语学习_教育专区。Post-1990 Generation Picky About Jobs: Research 对工作挑剔的“90 后” Members of the post-1990 generation looPost-19...  POST 报纸 9月5日_韩语学习_外语学习_教育专区。POST 报纸 9月5日 Post 报纸 9 月 5 日 单词:1、搜寻 v. 2、愿意的 adj. 3、吸引 v. 4、喜剧 n. ...  Ajax学习笔记_英语学习_外语学习_教育专区。Ajax 学习笔记 1. Ajax 是什么? 1...charset=utf-8&&
用户名: ...  post-test_英语学习_外语学习_教育专区。CME Post-Test This CME Post-Test contains questions for you to answer after you have reviewed all ofCME Post-Test...当前位置:
(1 次投票, 评分: 5.00, 总分: 5)
&Loading ...
HBase是一个分布式的、面向列的数据库,它和一般关系型数据库的最大区别是:HBase很适合于存储非结构化的数据,还有就是它基于列的而不是基于行的模式。
既然HBase是采用KeyValue的列存储,那Rowkey就是KeyValue的Key了,表示唯一一行。Rowkey也是一段二进制码流,最大长度为64KB,内容可以由使用的用户自定义。数据加载时,一般也是根据Rowkey的二进制序由小到大进行的。
HBase是根据Rowkey来进行检索的,系统通过找到某个Rowkey (或者某个 Rowkey 范围)所在的Region,然后将查询数据的请求路由到该Region获取数据。HBase的检索支持3种方式:
(1) 通过单个Rowkey访问,即按照某个Rowkey键值进行get操作,这样获取唯一一条记录;
(2) 通过Rowkey的range进行scan,即通过设置startRowKey和endRowKey,在这个范围内进行扫描。这样可以按指定的条件获取一批记录;
(3) 全表扫描,即直接扫描整张表中所有行记录。
HBASE按单个Rowkey检索的效率是很高的,耗时在1毫秒以下,每秒钟可获取条记录,不过非key列的查询很慢。
二.HBase的RowKey设计
2.1 设计原则
1.Rowkey长度原则
Rowkey是一个二进制码流,Rowkey的长度被很多开发者建议说设计在10~100个字节,不过建议是越短越好,不要超过16个字节。
原因如下:
(1)数据的持久化文件HFile中是按照KeyValue存储的,如果Rowkey过长比如100个字节,1000万列数据光Rowkey就要占用100*1000万=10亿个字节,将近1G数据,这会极大影响HFile的存储效率;
(2)MemStore将缓存部分数据到内存,如果Rowkey字段过长内存的有效利用率会降低,系统将无法缓存更多的数据,这会降低检索效率。因此Rowkey的字节长度越短越好。
(3)目前操作系统是都是64位系统,内存8字节对齐。控制在16个字节,8字节的整数倍利用操作系统的最佳特性。
2.Rowkey散列原则
如果Rowkey是按时间戳的方式递增,不要将时间放在二进制码的前面,建议将Rowkey的高位作为散列字段,由程序循环生成,低位放时间字段,这样将提高数据均衡分布在每个Regionserver实现负载均衡的几率。如果没有散列字段,首字段直接是时间信息将产生所有新数据都在一个RegionServer上堆积的热点现象,这样在做数据检索的时候负载将会集中在个别RegionServer,降低查询效率。
3.必须在设计上保证其唯一性。
2.2 应用场景
基于Rowkey的上述3个原则,应对不同应用场景有不同的Rowkey设计建议。
事务数据是带时间属性的,建议将时间信息存入到Rowkey中,这有助于提示查询检索速度。对于事务数据建议缺省就按天为数据建表,这样设计的好处是多方面的。按天分表后,时间信息就可以去掉日期部分只保留小时分钟毫秒,这样4个字节即可搞定。加上散列字段2个字节一共6个字节即可组成唯一Rowkey。
事务数据Rowkey设计:
第0字节 第1字节:散列字段 0~5;0000~0xFFFF)
第2字节 第3字节 第4字节 第5字节:时间字段(毫秒) 0~&#215;x05265BFF)
其余字节:扩展字段
针对统计数据的Rowkey设计
统计数据也是带时间属性的,统计数据最小单位只会到分钟(到秒预统计就没意义了)。同时对于统计数据我们也缺省采用按天数据分表,这样设计的好处无需多说。按天分表后,时间信息只需要保留小时分钟,那么0~1400只需占用两个字节即可保存时间信息。由于统计数据某些维度数量非常庞大,因此需要4个字节作为序列字段,因此将散列字段同时作为序列字段使用也是6个字节组成唯一Rowkey。
第0字节 第1字节 第2字节 第3字节:散列字段(序列字段)0&#215;xFFFFFFFF)
第4字节 第5字节:时间字段(分钟)0~5;F)
其余字节:扩展字段
同样这样的设计从操作系统内存管理层面无法节省开销,因为64位操作系统是必须8字节对齐。但是对于持久化存储中Rowkey部分可以节省25%的开销。预统计数据可能涉及到多次反复的重计算要求,需确保作废的数据能有效删除,同时不能影响散列的均衡效果,因此要特殊处理。
针对通用数据的Rowkey设计
通用数据采用自增序列作为唯一主键,用户可以选择按天建分表也可以选择单表模式。这种模式需要确保同时多个入库加载模块运行时散列字段(序列字段)的唯一性。可以考虑给不同的加载模块赋予唯一因子区别。
第0字节 第1字节 第2字节 第3字节:散列字段(序列字段)0&#215;xFFFFFFFF)
其余字节:扩展字段(可由多个用户字段组成)
支持多条件查询的RowKey设计
HBase按指定的条件获取一批记录时,使用的就是scan方法。 scan方法有以下特点:
(1)scan可以通过setCaching与setBatch方法提高速度(以空间换时间);
(2)scan可以通过setStartRow与setEndRow来限定范围。范围越小,性能越高。
通过巧妙的RowKey设计使我们批量获取记录集合中的元素挨在一起(应该在同一个Region下),可以在遍历结果时获得很好的性能。
(3)scan可以通过setFilter方法添加过滤器,这也是分页、多条件查询的基础。
在满足长度、三列、唯一原则后,我们需要考虑如何通过巧妙设计RowKey以利用scan方法的范围功能,使得获取一批记录的查询速度能提高。下例就描述如何将多个列组合成一个RowKey,使用scan的range来达到较快查询速度。
我们在表中存储的是文件信息,每个文件有5个属性:文件id(long,全局唯一)、创建时间(long)、文件名(String)、分类名(String)、所有者(User)。
我们可以输入的查询条件:文件创建时间区间(比如从120914期间创建的文件),文件名(“中国好声音”),分类(“综艺”),所有者(“浙江卫视”)。
假设当前我们一共有如下文件:
ID CreateTime Name Category UserID
中国好声音第1期 综艺 1
中国好声音第2期 综艺 1
中国好声音外卡赛 综艺 1
中国好声音第3期 综艺 1
中国好声音第4期 综艺 1
中国好声音选手采访 综艺花絮 2
中国好声音第5期 综艺 1
中国好声音录制花絮 综艺花絮 2
张玮独家专访 花絮 3
加多宝凉茶广告 综艺广告 4
这里UserID应该对应另一张User表,暂不列出。我们只需知道UserID的含义:
1代表 浙江卫视; 2代表 好声音剧组; 3代表 XX微博; 4代表赞助商。调用查询接口的时候将上述5个条件同时输入find(21001,”中国好声音”,”综艺”,”浙江卫视”)。此时我们应该得到记录应该有第1、2、3、4、5、7条。第6条由于不属于“浙江卫视”应该不被选中。我们在设计RowKey时可以这样做:采用UserID + CreateTime + FileID组成RowKey,这样既能满足多条件查询,又能有很快的查询速度。
需要注意以下几点:
(1)每条记录的RowKey,每个字段都需要填充到相同长度。假如预期我们最多有10万量级的用户,则userID应该统一填充至6位,如0002…
(2)结尾添加全局唯一的FileID的用意也是使每个文件对应的记录全局唯一。避免当UserID与CreateTime相同时的两个不同文件记录相互覆盖。
按照这种RowKey存储上述文件记录,在HBase表中是下面的结构:
rowKey(userID 6 + time 8 + fileID 6) name category ….
怎样用这张表?
在建立一个scan对象后,我们setStartRow(01),setEndRow(14)。
这样,scan时只扫描userID=1的数据,且时间范围限定在这个指定的时间段内,满足了按用户以及按时间范围对结果的筛选。并且由于记录集中存储,性能很好。
然后使用SingleColumnValueFilter(org.apache.hadoop.hbase.filter.SingleColumnValueFilter),共4个,分别约束name的上下限,与category的上下限。满足按同时按文件名以及分类名的前缀匹配。
(注意:使用SingleColumnValueFilter会影响查询性能,在真正处理海量数据时会消耗很大的资源,且需要较长的时间)
如果需要分页还可以再加一个PageFilter限制返回记录的个数。
三.应用案例
任何系统设计,都要按照具体业务场景来设计方案。在我们订单系统中,以订单号为维度来统计该订单被多少个用户查看过。
rowkey设计:订单号是一个long型长整数,订单号是自增的。如果直接以订单号为rowky,根据字典排序,会导致数据热读热写。因为订单号是自增的,写数据只会写到一个RegionServer中去,最新订单一般都会查询比较多,这样会造成一个RegionServer查询频繁,性能低。
方法1:将订单号倒置,减少热读热写。
方法2:将订单号md5加密,取前5位,作为散列字段。
还需要在rowkey上加上一个时间段,精确到分钟,例如。
列为:用户id,用户ip,用户访问时间
rowkey为:将订单号倒置+当前时间(精确到分钟)
查询通过scan来实现。 分页通过scan的StartRow和StopRow来实现。
本文固定链接:
【上一篇】【下一篇】
您可能还会对这些文章感兴趣!

我要回帖

更多关于 jenkins 添加全局变量 的文章

 

随机推荐