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