這次剛好有個需求是需要給金流一個流水號,但是由於cassandra設計上沒辦法像mssql有@@IDENTITY這種方便的取識別值方式,所以只好自己想辦法了,原本想說要找zookeeper或是snowflake這些分散式系統取流水號的方式,但是因為時間因素沒辦法研究這些東西,只好先想個方法硬上。
由於spec上的規格是九位的數字,所以研究了一下,決定將key值拿來md5後的hash轉成int,再取九碼出來(原本會是大約38~40位的數字),原則上在短時間內是不會遇到重複的情況,然後只要每次產生數字hash後,先確認cassandra內有沒有這個number hash,沒有的話再使用,有的話就重生一個;由於理論上這個number hash會發生一次重複的時間應該遠比cassandra最終同步的時間來的長,所以會遇到丟出重複流水號的機會可說是微乎其微,在有更好的解法之前這個方式應該可以加減用。
語法很簡單,大概就是這樣
import hashlib def md5(istr): return hashlib.md5(istr).hexdigest() def randNum(istr): return str(int(md5(istr),16))[:9] print md5('test') //098f6bcd4621d373cade4e832627b4f6 print randNum('test') //1270773689
跑起來結果就是這樣,不過下圖測試時我是取十位XD
小小記錄一下心得。
update一下,如果要取一個不到20位的數字,可以使用這個方式,str(uuid.uuid4().get_time())會回傳一個約19位的數字字串,我不曉得他會不會長到20,不過看來是可以用的,而且又不是亂數,剛好符合另一個需求,可賀可喜。
a=uuid.uuid4() print(a) //38015b71-d95a-4bd4-a1d2-f1d30bb165d2 print str(a.get_time())[:20] //852545210989763441
No comments:
Post a Comment