首頁  >  文章  >  後端開發  >  PHP高並發下產生唯一識別碼

PHP高並發下產生唯一識別碼

WBOY
WBOY原創
2016-08-08 09:06:351330瀏覽

如題,首先謝謝所有來回答的大牛.
描述一下問題:

<code>学习PHP过程中想通过实践编写一套推广系统。
推广地址:**http://xxxx.com/N4aF35aS7**
"N4aF35aS7"作为一个识别码。</code>

現在的問題是:

<code>PHP有函数以微秒级别获取字符,但是如果考虑到高
并发(具体有多高不讨论,但需要考虑进来)可能会
有重复?
另外,识别码在生成上有规范:
1.长度固定(8位左右,太长地址不友好)
2.组合形式为大写、小写字母,数字(参考百度网盘分享地址)
3.绝对不重复,这点很重要
4.没什么要求了,再谢谢来回答的人。</code>

回覆內容:

如題,首先謝謝所有來回答的大牛.
描述一下問題:

<code>学习PHP过程中想通过实践编写一套推广系统。
推广地址:**http://xxxx.com/N4aF35aS7**
"N4aF35aS7"作为一个识别码。</code>

現在的問題是:

<code>PHP有函数以微秒级别获取字符,但是如果考虑到高
并发(具体有多高不讨论,但需要考虑进来)可能会
有重复?
另外,识别码在生成上有规范:
1.长度固定(8位左右,太长地址不友好)
2.组合形式为大写、小写字母,数字(参考百度网盘分享地址)
3.绝对不重复,这点很重要
4.没什么要求了,再谢谢来回答的人。</code>

我提一種方法:預處理標識符

  1. 事先透過演算法產生絕對不重複的標識符,這個過程中可以自己進行測試,而且因為是預處理的,所以不需要考慮時間和演算法複雜性。

  2. 將產生的不重複的識別碼寫入資料庫

  3. 在高並發的場景下只使用讀取操作

上面主要是解決了高並發下的快速回應問題,那麼唯一性如何保證呢?
有兩個思路:

  1. 使用佇列進行讀取,確保所有的讀取都是透過唯一的佇列來完成,例如使用redis的pop操作

  2. 使用sql的update指令,這個時候需要另一個欄位userid, 偽代碼:update TABLE set userid = $userid where userid = 0 limit 1;,然後再使用userid進行對應的識別碼即可。

最後,我堅持的觀點是:一開始的時候就把程式設計的盡量安全,注意,安全方面的問題一定要高優先考慮。
至於說,真正的場景中有哪些「高並發」的場景呢?我只想說,出了問題還是要程式設計師背鍋。

如果要求絕對不重複那我感覺思路有兩個
1.每次隨機產生新建的id數據持久化,然後每次隨機產生的數據查歷史數據是否重複(但是這每次要數據持久化肯定比較消耗性能)
2.按規律累加(例如按日期時間戳balabala),這樣產生過的就不會重複,但是高並發怎麼不重複應該就要考慮一下了。

想問問題主比較擔心的是並發狀態下產生相同的識別碼還是比較擔心會產生歷史重複的識別碼?

如果擔心是並發狀態的話應該考慮你說的微秒級別字符加一定量的隨機數就好了(每位隨機數可以在48-122之間按ASCII轉換為字符),加多幾位就好了,雖說理論上沒有絕對不重複但是機率應該還是很小了

如果考慮歷史重複那我想到的就是一開始說的那兩條了

用鎖機制試試看。 。

1 寫文件每次+1
2 你既然是推廣系統這個唯一碼只要你帶上用戶id那麼就唯一
3 看到這種什麼高並發的問題就覺得是自己閒的蛋疼,整個互聯網要處理高併發的公司真不多,拿來那麼多高並發。感覺現在就是,框架,系統,高並發,快取成為了程式設計師的口頭禪了。

可以產生一條 插入資料庫 建個唯一索引 讓資料庫給你去重

根據資料庫中唯一ID產生一個對應的62進位字串。
比較多的文章分析短網址的規則都是產生62進制,理論上ID不重複也不會重複產生字串,但是長度是會變的。看是否可接受。
沒有那麼多真正高併發的事,要求高用用戶ID也是一種辦法。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn