目前,比较火的nosql数据库,如MongoDB,Redis,Riak都提供了类似incr原子行操作。
下面是PHP版的一种实现方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
$ cat Lib/Action/OrdersnumAction.class.php <?php /** * 基于Redis的全局订单号id * * @author liujingyu * @copyright liujingyu, 11 八月, 2014 **/ class OrdersnumAction extends Action { private $_r; private $_host; private $_port; private $_passwd; private $_prefix; private $_len; function __construct() { try { $redisconfig = array( 'host'=>'xxx.xx.xx.x 'port'=>6379, 'password'=>'xxxxxxx', 'prefix'=>'order_num', 'len'=>6, ); $this->setBuilder($redisconfig); $this->_r = new redis; $ret = $this->_r->connect($this->_host, $this->_port); if (!$ret) { die("[redis connect error]"); } $this->_r->auth($this->_passwd); } catch (Exception $e) { trace($e->getMessage()); } } private function setBuilder($redisconfig) { $this->_host = $redisconfig['host']; $this->_port = $redisconfig['port']; $this->_passwd = $redisconfig['password']; $this->_prefix = $redisconfig['prefix']; $this->_len = $redisconfig['len']; } /** * 生成当天全局唯一自增id * * @param integer $key * * @return $id * @author liujingyu **/ private function nextId($key) { $id = $this->_r->incr($this->_prefix.":".$key); $l = strlen($id); if ($l>$this->_len) { return $id; } else { return str_repeat(0, $this->_len-$l).$id; } } /** * 获取订单号 * * @return integer * @author liujingyu **/ public function getOrdersNum() { $key = date('ymd', time()); return $key.$this->nextId($key); } } |
采用的Redis中incr原子操作,并发量7w(单机,2核,2GB,centos6.5)。
类似天猫双十一这样的电商,提高并发量采用Redis list类型预生成,hash取模分散到多个实例中。进而达到无限扩展容。