分布式id php,PHP生成类MongoId的分布式主键

今天写了个简单的PHP函数,用来生成按时间增长的全局唯一主键。这类主键的作用主要是在分布式环境中保证每条数据能够有一个唯一标识,同时又有一定的自增长性以提高索引效率。当然也可以用来掩人耳目,毕竟一个简单的int类型的自增ID的话,很容易让人猜到你的数据量有多少了。

分布式环境下数据主键的生成方法其实是蛮多的,比如使用Mysql之类的自增ID,只需要设置好自增步长和起始值就可以满足基本要求了,还有像目前流行的文档型数据库MongoDB就提供了一个MongoId的实现,可以在客户端直接生成长度为24的自增长型全局字符串主键。今天写的这个PHP函数就是参考MongoId的算法实现的,不需要安装MongoDB扩展也可以使用。

MongoDB的PHP扩展中有一个C语言版本的 generate_id 函数的实现,可以参考 https://github.com/mongodb/mongo-php-driver/blob/master/types/id.c。基本上,每个 MongoId 具有 12 个字节(使它的字符串形式是 24 个十六进制字符),前四个字节是一个时间戳(timestamp int,单位为秒),后三个是客户端主机名的 hash 摘要,然后两个是运行脚本的进程 ID, 最后三位是一个以随机数作为起始值的自增值。从这个描述里我们也可以看出,MongoId的生成基本是向上增长的,也不太可能出现重复,是一个比较优质的主键生成实现。

下面贴一个PHP版本的实现。如有不妥,还请指出。

/**

* Generate an ID, constructed using:

* a 4-byte value representing the seconds since the Unix epoch,

* a 3-byte machine identifier,

* a 2-byte process id, and

* a 3-byte counter, starting with a random value.

* Just like a MongoId string.

*

* @link http://docs.mongodb.org/manual/reference/object-id/

* @return string 24 hexidecimal characters

*/

function generate_id_hex()

{

static $i = 0;

$i OR $i = mt_rand(1, 0x7FFFFF);

return sprintf("%08x%06x%04x%06x",

/* 4-byte value representing the seconds since the Unix epoch. */

time() & 0xFFFFFFFF,

/* 3-byte machine identifier.

*

* On windows, the max length is 256. Linux doesn't have a limit, but it

* will fill in the first 256 chars of hostname even if the actual

* hostname is longer.

*

* From the GNU manual:

* gethostname stores the beginning of the host name in name even if the

* host name won't entirely fit. For some purposes, a truncated host name

* is good enough. If it is, you can ignore the error code.

*

* crc32 will be better than Times33. */

crc32(substr((string)gethostname(), 0, 256)) >> 8 & 0xFFFFFF,

/* 2-byte process id. */

getmypid() & 0xFFFF,

/* 3-byte counter, starting with a random value. */

$i = $i > 0xFFFFFE ? 1 : $i + 1

);

}

调用结果:

a@L:~/develop$ php -f generate_id_hex.php

string(24) "53352f1b00ad68781531d378"

string(24) "53352f1b00ad68781531d379"

string(24) "53352f1b00ad68781531d37a"

string(24) "53352f1b00ad68781531d37b"

string(24) "53352f1b00ad68781531d37c"

string(24) "53352f1b00ad68781531d37d"

string(24) "53352f1b00ad68781531d37e"

string(24) "53352f1b00ad68781531d37f"

string(24) "53352f1b00ad68781531d380"

string(24) "53352f1b00ad68781531d381"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值