我想如何从网页上扒ts视频直接扒下来视频,各位高手们有没有什么好办法?

分布式自增ID解决方案 twitter/snowflake JAVA版 谁可以帮忙改写成PHP版本的呢?
毫秒级时间41位+机器ID 10位+毫秒内序列12位
1.twitter/snowflake
下面是淘宝一个人改写成JAVA的,&
目前我需要PHP版本。 哪位朋友可以抽空改写下呢?
俺又来求助啦~
public class IdWorker {
private final long workerId;
private final static long twepoch = 8L;
private long sequence = 0L;
private final static long workerIdBits = 4L;
public final static long maxWorkerId = -1L ^ -1L && workerIdB
private final static long sequenceBits = 10L;
private final static long workerIdShift = sequenceB
private final static long timestampLeftShift = sequenceBits + workerIdB
public final static long sequenceMask = -1L ^ -1L && sequenceB
private long lastTimestamp = -1L;
public IdWorker(final long workerId) {
if (workerId & this.maxWorkerId || workerId & 0) {
throw new IllegalArgumentException(String.format(
&worker Id can't be greater than %d or less than 0&,
this.maxWorkerId));
this.workerId = workerId;
public synchronized long nextId() {
long timestamp = this.timeGen();
if (this.lastTimestamp == timestamp) {
this.sequence = (this.sequence + 1) & this.sequenceM
if (this.sequence == 0) {
System.out.println(&###########& + sequenceMask);
timestamp = this.tilNextMillis(this.lastTimestamp);
this.sequence = 0;
if (timestamp & this.lastTimestamp) {
throw new Exception(
String.format(
&Clock moved backwards.
Refusing to generate id for %d milliseconds&,
this.lastTimestamp - timestamp));
} catch (Exception e) {
e.printStackTrace();
this.lastTimestamp =
long nextId = ((timestamp - twepoch && timestampLeftShift))
| (this.workerId && this.workerIdShift) | (this.sequence);
System.out.println(&timestamp:& + timestamp + &,timestampLeftShift:&
+ timestampLeftShift + &,nextId:& + nextId + &,workerId:&
+ workerId + &,sequence:& + sequence);
return nextId;
private long tilNextMillis(final long lastTimestamp) {
long timestamp = this.timeGen();
while (timestamp &= lastTimestamp) {
timestamp = this.timeGen();
private long timeGen() {
return System.currentTimeMillis();
public static void main(String[] args){
IdWorker worker2 = new IdWorker(2);
System.out.println(worker2.nextId());
目前是修改成这样, 可是在长整型计算的时候((sprintf('%.0f', $timestamp) - sprintf('%.0f', self::$twepoch) )) 有负数产生, 产生的ID会收影响为-的
class Idwork
const debug = 1;
static $workerId;
static $twepoch = 8;
static $sequence = 0;
const workerIdBits = 4;
static $maxWorkerId = 15;
const sequenceBits = 10;
static $workerIdShift = 10;
static $timestampLeftShift = 14;
static $sequenceMask = 1023;
static $lastTimestamp = -1;
function __construct($workId){
if($workId & self::$maxWorkerId || $workId& 0 )
throw new Exception(&worker Id can't be greater than 15 or less than 0&);
self::$workerId=$workId;
echo 'logdebug-&__construct()-&self::$workerId:'.self::$workerId;
echo '&/br&';
function timeGen(){
//获得当前时间戳
$time = explode(' ', microtime());
$time2= substr($time[0], 2, 3);
$timestramp = $time[1].$time2;
echo 'logdebug-&timeGen()-&$timestramp:'.$time[1].$time2;
echo '&/br&';
$time[1].$time2;
tilNextMillis($lastTimestamp) {
$timestamp = $this-&timeGen();
while ($timestamp &= $lastTimestamp) {
$timestamp = $this-&timeGen();
echo 'logdebug-&tilNextMillis()-&$timestamp:'.$
echo '&/br&';
$timestamp=$this-&timeGen();
echo 'logdebug-&nextId()-&self::$lastTimestamp1:'.self::$lastT
echo '&/br&';
if(self::$lastTimestamp == $timestamp) {
self::$sequence = (self::$sequence + 1) & self::$sequenceM
if (self::$sequence == 0) {
echo &###########&.self::$sequenceM
$timestamp = $this-&tilNextMillis(self::$lastTimestamp);
echo 'logdebug-&nextId()-&self::$lastTimestamp2:'.self::$lastT
echo '&/br&';
self::$sequence
echo 'logdebug-&nextId()-&self::$sequence:'.self::$
echo '&/br&';
if ($timestamp & self::$lastTimestamp) {
throw new Excwption(&Clock moved backwards.
Refusing to generate id for &.(self::$lastTimestamp-$timestamp).& milliseconds&);
self::$lastTimestamp
echo 'logdebug-&nextId()-&self::$lastTimestamp3:'.self::$lastT
echo '&/br&';
echo 'logdebug-&nextId()-&(($timestamp - self::$twepoch && self::$timestampLeftShift )):'.((sprintf('%.0f', $timestamp) - sprintf('%.0f', self::$twepoch) ));
echo '&/br&';
$nextId = ((sprintf('%.0f', $timestamp) - sprintf('%.0f', self::$twepoch)
)) | ( self::$workerId && self::$workerIdShift ) | self::$
echo 'timestamp:'.$timestamp.'-----';
echo 'twepoch:'.sprintf('%.0f', self::$twepoch).'-----';
echo 'timestampLeftShift ='.self::$timestampLeftShift.'-----';
echo 'nextId:'.$nextId.'----';
echo 'workId:'.self::$workerId.'-----';
echo 'workerIdShift:'.self::$workerIdShift.'-----';
return $nextId;
$Idwork = new Idwork(1);
$a= $Idwork-&nextId();
$Idwork = new Idwork(2);
$a= $Idwork-&nextId();
public static void main(String[] args) {
Thread t = new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
StringBuffer s = new StringBuffer();
for (int i = 0; i & 1000; i++) {
IdWorker worker2 = new IdWorker(2);
s.append(worker2.nextId() + "\n");
s.append(worker2.nextId() + "\n");
s.append(worker2.nextId() + "\n");
s.append(worker2.nextId() + "\n");
s.append(worker2.nextId() + "\n");
FileUtils.writeStringToFile(new File("f:/1.txt"), s.toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
t.start();
Thread t2 = new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
StringBuffer s = new StringBuffer();
for (int i = 0; i & 1000; i++) {
IdWorker worker2 = new IdWorker(2);
s.append(worker2.nextId() + "\n");
s.append(worker2.nextId() + "\n");
s.append(worker2.nextId() + "\n");
s.append(worker2.nextId() + "\n");
s.append(worker2.nextId() + "\n");
FileUtils.writeStringToFile(new File("f:/2.txt"), s.toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
t2.start();
正确的测试方式:
public class IdWorkerTest
public static void main(String[] args)
Thread t = new Thread(new Runnable()
public void run()
StringBuffer s = new StringBuffer();
IdWorker worker2 = new IdWorker(2);
for (int i = 0; i & 1000; i++)
s.append(worker2.nextId() + "\n");
s.append(worker2.nextId() + "\n");
s.append(worker2.nextId() + "\n");
s.append(worker2.nextId() + "\n");
s.append(worker2.nextId() + "\n");
FileUtils.writeStringToFile(new File("c:/project/1.txt"), s.toString());
} catch (IOException e)
e.printStackTrace();
t.start();
Thread t2 = new Thread(new Runnable()
public void run()
StringBuffer s = new StringBuffer();
IdWorker worker2 = new IdWorker(3);
for (int i = 0; i & 1000; i++)
s.append(worker2.nextId() + "\n");
s.append(worker2.nextId() + "\n");
s.append(worker2.nextId() + "\n");
s.append(worker2.nextId() + "\n");
s.append(worker2.nextId() + "\n");
FileUtils.writeStringToFile(new File("c:/project/2.txt"), s.toString());
} catch (IOException e)
e.printStackTrace();
t2.start();
分布式自增ID。。。。难道是为了容灾???63位字符为什么不用UUID
--- 共有 1 条评论 ---
UUID 不是纯数字的。 并且也没有前后顺序性,分布式系统唯一ID生成方案汇总 - 推酷
分布式系统唯一ID生成方案汇总
系统唯一ID是我们在设计一个系统的时候常常会遇见的问题,也常常为这个问题而纠结。生成ID的方法有很多,适应不同的场景、需求以及性能要求。所以有些比较复杂的系统会有多个ID生成的策略。下面就介绍一些常见的ID生成策略。
1. 数据库自增长序列或字段
最常见的方式。利用数据库,全数据库唯一。
1)简单,代码方便,性能可以接受。
2)数字ID天然排序,对分页或者需要排序的结果很有帮助。
1)不同数据库语法和实现不同,数据库迁移的时候或多数据库版本支持的时候需要处理。
2)在单个数据库或读写分离或一主多从的情况下,只有一个主库可以生成。有单点故障的风险。
3)在性能达不到要求的情况下,比较难于扩展。
4)如果遇见多个系统需要合并或者涉及到数据迁移会相当痛苦。
5)分表分库的时候会有麻烦。
优化方案:
1)针对主库单点,如果有多个Master库,则每个Master库设置的起始数字不一样,步长一样,可以是Master的个数。比如:Master1 生成的是 1,4,7,10,Master2生成的是2,5,8,11 Master3生成的是 3,6,9,12。这样就可以有效生成集群中的唯一ID,也可以大大降低ID生成数据库操作的负载。
常见的方式。可以利用数据库也可以利用程序生成,一般来说全球唯一。
1)简单,代码方便。
2)生成ID性能非常好,基本不会有性能问题。
3)全球唯一,在遇见数据迁移,系统数据合并,或者数据库变更等情况下,可以从容应对。
1)没有排序,无法保证趋势递增。
2)UUID往往是使用字符串存储,查询的效率比较低。
3)存储空间比较大,如果是海量数据库,就需要考虑存储量的问题。
4)传输数据量大
5)不可读。
3. UUID的变种
1)为了解决UUID不可读,可以使用UUID to Int64的方法。及
/// &summary&
/// 根据GUID获取唯一数字序列
/// &/summary&
public static long GuidToInt64()
byte[] bytes = Guid.NewGuid().ToByteArray();
return BitConverter.ToInt64(bytes, 0);
2)为了解决UUID无序的问题,NHibernate在其主键生成方式中提供了Comb算法(combined guid/timestamp)。保留GUID的10个字节,用另6个字节表示GUID生成的时间(DateTime)。
/// &summary&
/// Generate a new &see cref=&Guid&/& using the comb algorithm.
/// &/summary&
private Guid GenerateComb()
byte[] guidArray = Guid.NewGuid().ToByteArray();
DateTime baseDate = new DateTime();
DateTime now = DateTime.N
// Get the days and milliseconds which will be used to build
//the byte string
TimeSpan days = new TimeSpan(now.Ticks - baseDate.Ticks);
TimeSpan msecs = now.TimeOfD
// Convert to a byte array
// Note that SQL Server is accurate to 1/300th of a
// millisecond so we divide by 3.333333
byte[] daysArray = BitConverter.GetBytes(days.Days);
byte[] msecsArray = BitConverter.GetBytes((long)
(msecs.TotalMilliseconds / 3.333333));
// Reverse the bytes to match SQL Servers ordering
Array.Reverse(daysArray);
Array.Reverse(msecsArray);
// Copy the bytes into the guid
Array.Copy(daysArray, daysArray.Length - 2, guidArray,
guidArray.Length - 6, 2);
Array.Copy(msecsArray, msecsArray.Length - 4, guidArray,
guidArray.Length - 4, 4);
return new Guid(guidArray);
用上面的算法测试一下,得到如下的结果:作为比较,前面3个是使用COMB算法得出的结果,最后12个字符串是时间序(统一毫秒生成的3个UUID),过段时间如果再次生成,则12个字符串会比图示的要大。后面3个是直接生成的GUID。
如果想把时间序放在前面,可以生成后改变12个字符串的位置,也可以修改算法类的最后两个Array.Copy。
4. Redis生成ID
当使用数据库来生成ID性能不够要求的时候,我们可以尝试使用Redis来生成ID。这主要依赖于Redis是单线程的,所以也可以用生成全局唯一的ID。可以用Redis的原子操作 INCR和INCRBY来实现。
可以使用Redis集群来获取更高的吞吐量。假如一个集群中有5台Redis。可以初始化每台Redis的值分别是1,2,3,4,5,然后步长都是5。各个Redis生成的ID为:
A:1,6,11,16,21
B:2,7,12,17,22
C:3,8,13,18,23
D:4,9,14,19,24
E:5,10,15,20,25
这个,随便负载到哪个机确定好,未来很难做修改。但是3-5台服务器基本能够满足器上,都可以获得不同的ID。但是步长和初始值一定需要事先需要了。使用Redis集群也可以方式单点故障的问题。
另外,比较适合使用Redis来生成每天从0开始的流水号。比如订单号=日期+当日自增长号。可以每天在Redis中生成一个Key,使用INCR进行累加。
1)不依赖于数据库,灵活方便,且性能优于数据库。
2)数字ID天然排序,对分页或者需要排序的结果很有帮助。
1)如果系统中没有Redis,还需要引入新的组件,增加系统复杂度。
2)需要编码和配置的工作量比较大。
5. Twitter的snowflake算法
snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。具体实现的代码可以参看
C#代码如下:
/// &summary&
/// From: /twitter/snowflake
/// An object that generates IDs.
/// This is broken into a separate class in case
/// we ever want to support multiple worker threads
/// per process
/// &/summary&
public class IdWorker
private long workerId;
private long datacenterId;
private long sequence = 0L;
private static long twepoch = 7L;
private static long workerIdBits = 5L;
private static long datacenterIdBits = 5L;
private static long maxWorkerId = -1L ^ (-1L && (int)workerIdBits);
private static long maxDatacenterId = -1L ^ (-1L && (int)datacenterIdBits);
private static long sequenceBits = 12L;
private long workerIdShift = sequenceB
private long datacenterIdShift = sequenceBits + workerIdB
private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdB
private long sequenceMask = -1L ^ (-1L && (int)sequenceBits);
private long lastTimestamp = -1L;
private static object syncRoot = new object();
public IdWorker(long workerId, long datacenterId)
// sanity check for workerId
if (workerId & maxWorkerId || workerId & 0)
throw new ArgumentException(string.Format(&worker Id can't be greater than %d or less than 0&, maxWorkerId));
if (datacenterId & maxDatacenterId || datacenterId & 0)
throw new ArgumentException(string.Format(&datacenter Id can't be greater than %d or less than 0&, maxDatacenterId));
this.workerId = workerId;
this.datacenterId = datacenterId;
public long nextId()
lock (syncRoot)
long timestamp = timeGen();
if (timestamp & lastTimestamp)
throw new ApplicationException(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) && (int)timestampLeftShift) | (datacenterId && (int)datacenterIdShift) | (workerId && (int)workerIdShift) |
protected long tilNextMillis(long lastTimestamp)
long timestamp = timeGen();
while (timestamp &= lastTimestamp)
timestamp = timeGen();
protected long timeGen()
return (long)(DateTime.UtcNow - new DateTime(, 0, 0, 0, DateTimeKind.Utc)).TotalM
测试代码如下:
private static void TestIdWorker()
HashSet&long& set = new HashSet&long&();
IdWorker idWorker1 = new IdWorker(0, 0);
IdWorker idWorker2 = new IdWorker(1, 0);
Thread t1 = new Thread(() =& DoTestIdWoker(idWorker1, set));
Thread t2 = new Thread(() =& DoTestIdWoker(idWorker2, set));
t1.IsBackground =
t2.IsBackground =
t1.Start();
t2.Start();
Thread.Sleep(30000);
t1.Abort();
t2.Abort();
catch (Exception e)
Console.WriteLine(&done&);
private static void DoTestIdWoker(IdWorker idWorker, HashSet&long& set)
while (true)
long id = idWorker.nextId();
if (!set.Add(id))
Console.WriteLine(&duplicate:& + id);
Thread.Sleep(1);
snowflake算法可以根据自身项目的需要进行一定的修改。比如估算未来的数据中心个数,每个数据中心的机器数以及统一毫秒可以能的并发数来调整在算法中所需要的bit数。
1)不依赖于数据库,灵活方便,且性能优于数据库。
2)ID按照时间在单机上是递增的。
1)在单机上是递增的,但是由于涉及到分布式环境,每台机器上的时钟不可能完全同步,也许有时候也会出现不是全局递增的情况。
6. 利用zookeeper生成唯一ID
zookeeper主要通过其znode数据版本来生成序列号,可以生成32位和64位的数据版本号,客户端可以使用这个版本号来作为唯一的序列号。
很少会使用zookeeper来生成唯一ID。主要是由于需要依赖zookeeper,并且是多步调用API,如果在竞争较大的情况下,需要考虑使用分布式锁。因此,性能在高并发的分布式环境下,也不甚理想。
7. MongoDB的ObjectId
MongoDB的ObjectId和snowflake算法类似。它设计成轻量型的,不同的机器都能用全局唯一的同种方法方便地生成它。MongoDB 从一开始就设计用来作为分布式数据库,处理多个节点是一个核心要求。使其在分片环境中要容易生成得多。
其格式如下:
前4 个字节是从标准纪元开始的时间戳,单位为秒。时间戳,与随后的5 个字节组合起来,提供了秒级别的唯一性。由于时间戳在前,这意味着ObjectId 大致会按照插入的顺序排列。这对于某些方面很有用,如将其作为索引提高效率。这4 个字节也隐含了文档创建的时间。绝大多数客户端类库都会公开一个方法从ObjectId 获取这个信息。
接下来的3 字节是所在主机的唯一标识符。通常是机器主机名的散列值。这样就可以确保不同主机生成不同的ObjectId,不产生冲突。
为了确保在同一台机器上并发的多个进程产生的ObjectId 是唯一的,接下来的两字节来自产生ObjectId 的进程标识符(PID)。
前9 字节保证了同一秒钟不同机器不同进程产生的ObjectId 是唯一的。后3 字节就是一个自动增加的计数器,确保相同进程同一秒产生的ObjectId 也是不一样的。同一秒钟最多允许每个进程拥有 216)个不同的ObjectId。
实现的源码可以到MongoDB官方网站下载。
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致966,690 二月 独立访问用户
语言 & 开发
架构 & 设计
文化 & 方法
您目前处于:
Apache Ignite(四):基于Ignite的分布式ID生成器
Apache Ignite(四):基于Ignite的分布式ID生成器
日. 估计阅读时间:
不到一分钟
IgniteAtomicSequence接口提供了分布式的原子性序列,类似于分布式原子性的Long类型,但是他的值只能增长,他特有的功能是支持预留一定范围的序列值,来避免每次序列获取下一个值时都需要的昂贵的网络消耗和缓存更新,也就是,当在一个原子性序列上执行了incrementAndGet()(或者任何其他的原子性操作),数据结构会往前预留一定范围的序列值,他会保证对于这个序列实例来说跨集群的唯一性。这个类型的使用是非常简单的,相关代码如下:Ignite ignite = Ignition.start();
IgniteAtomicSequence seq = ignite.atomicSequence("seqName",//序列名
0, //初始值
true//如果序列不存在则创建
for (int i = 0; i < 20; i++) {
long currentValue = seq.get();//获取当前值
long newValue = seq.incrementAndGet();//先加1再取值
这个样例中创建的seq,初始值从0开始,然后递增,看上去很完美,但是当系统不管什么原因重启后,就又会从0开始,这显然是无法保证唯一性的,因此这个方法还是不能在生产环境下使用。
3.基于IgniteAtomicSequence的分布式ID生成器
相关厂商内容
相关赞助商
QCon北京-18日,北京&国家会议中心,
按照前述,直接按照初始值0创建IgniteAtomicSequence,是有很大风险的,无法在生产环境下使用,而且存在长度不固定问题,所以还需要进一步想办法,研究的重点在于解决初始值的问题。
因为IgniteAtomicSequence的值为long型,而在Java中long类型的最大值是4775807,这个数值长度为19位,对于实际应用来说,是一个很大的值,但是对于常见的没有环境依赖的ID生成器来说,还是比较短的。因此我们打算在这方面做文章。
因为系统重置的一个重要指标就是时间,那么我们以时间作为参照,然后加上一个扩展,可能是一个比较理想的选择,我们以如下的规则作为初始值:
时间的yyyyMMddHHmmss+00000
这个长度正好是19位,然后每次加1,因为现在是2016年,这个规则在常规应用场景中,是不会超过long类型的最大值的。
但是,这个规则存在一个风险,就是假设不考虑实际应用和实际性能,如果增加操作业务量特别大,会使这个序列值快速进位,如果某个时间节点宕机后瞬间重启,是有可能存在重启后的初始值小于原来的最大值的,这时就无法保证唯一性了。下面就对这个理论情况下的最大值做一个计算,然后开发者就会知道在自己的应用中如何改进这个规则以满足个性化需求了。
4.理论极限和性能
假定不考虑实际性能,我们以最简单的情况为例,就是启动后一秒钟内访问达到峰值,然后宕机后瞬间重启这种情况,这个很容易就能看出来,不需要计算,就是5个0对应的最大值10万,以此类推,考虑到时间的进位和十进制进位的不同,我们可以计算出一分钟后、一小时后、一天后、一月后、一年后宕机换算出的交易量的极大值,如下:
以1分钟为例进行说明,假设初始值为1200000,一分钟后宕机瞬间重启,对应的初始值为1200000,这个差额是,对应的每秒交易量为16.6万。
从上图来看,对于这样的规则,能承载的交易量还是很大的,当今世界最繁忙的交易系统,也不会超过这个极限情况下的极值,也就是说,这个规则就目前来说,具有普遍适用性。
而在实际生产中,瞬间重启是不存在的,随着重启时间向后推移,新的初始值会和原来的最大值拉开差距,更不可能出现冲突了。
关于性能,我在一台2011年的旧笔记本上进行测试,很容易就能达到50K/s的序列生成速度,这个还是可以的,但是这是在开启预留的前提下实现的,如果不开启预留,性能可能下降到13K/s。在一个具体的集群环境下,通常不会拿Ignite单独建立服务做ID分发中心,所以实际环境下性能能不能满足需求,开发者需要自行进行测试,评估然后做选择。另外,开启了预留会导致最终生成的ID可能不是随时间线性增长的,这个也需要注意。
5.常见分布式ID生成器对比
前述的基于Ignite的分布式ID生成器,优点是实现简单,将一个jar包嵌入应用后ID生成系统和应用生命周期一致,设置了备份后不存在单点故障,数值线性递增可比较大小,规则按照业务定制后可以做得更短,如果转成十六进制后,会非常短,不依赖数据库,不对数据库产生压力,缺点可能就是性能以及一些特定的业务需求了。
生成全局唯一ID的需求是刚性的,尤其是分布式环境中,问题显得尤为复杂。当前,这方面的实现方案非常多,通用的不通用的,本文不做详细的论述,只做简单的列举:
UUID优点是性能好,缺点是比较长,128位,无规则,无法比较大小。
ID分发中心比如twitter的snowflake服务,可以做到高性能,高可用,低延迟,时间上有序,缺点就是使整个系统变得复杂,维护工作量加大。
MongoDB的ObjectID(类似UUID)MongoDB的驱动中提供了objectId的生成功能,优点是相对于UUID要短些,时间上有序,而且这个id包含了很多有用的信息,解码后就可以获得。
数据库生成有很多的基于数据库的方案,比如基于Oracle和PostgreSQL的序列,Flickr和Instagram也有基于数据库的比较复杂的方案。
其他根据不同的业务场景,可以做出各种各样的、满足各种需求的ID生成方案,需求越多,实现也会越复杂。
分布式ID生成策略有很多的实现方案,各有优缺点,本文又提出了一个基于Apache Ignite的新方案,应该说没有最完美的,只有最符合实际业务需求的,开发者需要做的就是做详细的、综合的比较,然后选择最适合自己的方案。
Author Contacted
告诉我们您的想法
允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p
当有人回复此评论时请E-mail通知我
允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p
当有人回复此评论时请E-mail通知我
允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p
当有人回复此评论时请E-mail通知我
赞助商链接
InfoQ每周精要
通过个性化定制的新闻邮件、RSS Feeds和InfoQ业界邮件通知,保持您对感兴趣的社区内容的时刻关注。
架构 & 设计
文化 & 方法
<及所有内容,版权所有 &#169;
C4Media Inc.
服务器由 提供, 我们最信赖的ISP伙伴。
北京创新网媒广告有限公司
京ICP备号-7
注意:如果要修改您的邮箱,我们将会发送确认邮件到您原来的邮箱。
使用现有的公司名称
修改公司名称为:
公司性质:
使用现有的公司性质
修改公司性质为:
使用现有的公司规模
修改公司规模为:
使用现在的国家
使用现在的省份
Subscribe to our newsletter?
Subscribe to our industry email notices?
我们发现您在使用ad blocker。
我们理解您使用ad blocker的初衷,但为了保证InfoQ能够继续以免费方式为您服务,我们需要您的支持。InfoQ绝不会在未经您许可的情况下将您的数据提供给第三方。我们仅将其用于向读者发送相关广告内容。请您将InfoQ添加至白名单,感谢您的理解与支持。

我要回帖

更多关于 网页扒视频 的文章

 

随机推荐