新聞中心
Redis中浮動(dòng)金額設(shè)置策略分析

創(chuàng)新互聯(lián)公司主營(yíng)雁塔網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,app軟件開發(fā),雁塔h5重慶小程序開發(fā)搭建,雁塔網(wǎng)站營(yíng)銷推廣歡迎雁塔等地區(qū)企業(yè)咨詢
Redis(Remote Dictionary Server)是一種高性能的開源內(nèi)存數(shù)據(jù)存儲(chǔ)系統(tǒng)。它支持?jǐn)?shù)據(jù)的持久化和復(fù)制,并且可用于緩存、消息隊(duì)列和數(shù)據(jù)庫(kù)等多種用途。對(duì)于一些大型電商網(wǎng)站或金融交易系統(tǒng)而言,處理資金流轉(zhuǎn)時(shí)需要考慮高并發(fā)、高可用、高安全等多種因素,其中,浮動(dòng)金額截取更是一個(gè)重要的策略,為了滿足上述要求,Redis采用Hash結(jié)構(gòu)體進(jìn)行存儲(chǔ),采用set/bitsets等數(shù)據(jù)結(jié)構(gòu)來(lái)進(jìn)行動(dòng)態(tài)浮動(dòng)金額截取。
1、 Hash存儲(chǔ):
Hash是Redis的一種內(nèi)置數(shù)據(jù)結(jié)構(gòu),它類似于Python中的字典數(shù)據(jù)類型,主要用于存儲(chǔ)對(duì)象。具體地,Hash以一個(gè)字符串類型的鍵和一個(gè)字典類型的值之間的映射關(guān)系進(jìn)行存儲(chǔ)。在實(shí)際場(chǎng)景中,我們可以利用Hash來(lái)存儲(chǔ)用戶信息、產(chǎn)品信息、訂單信息等等。在使用Hash進(jìn)行存儲(chǔ)時(shí),我們可以通過(guò)對(duì)應(yīng)的鍵和值將其和其他數(shù)據(jù)結(jié)構(gòu)進(jìn)行聯(lián)合使用。
2、 set/bitsets浮動(dòng)金額截取:
在某些高并發(fā)的金融交易系統(tǒng)中,為了避免錯(cuò)誤的浮點(diǎn)計(jì)算及其誤差累計(jì)問(wèn)題,可以通過(guò)設(shè)計(jì)浮動(dòng)金額截取策略,即將實(shí)際計(jì)算得到的金額轉(zhuǎn)化成整型數(shù)值,并將其存儲(chǔ)在Redis中,以保證數(shù)據(jù)的準(zhǔn)確性和正確性。實(shí)現(xiàn)方法是將60分作為小單位,1元作為大單位,以及一個(gè)限制位,如果小數(shù)部分超過(guò)限制位,直接向整數(shù)部分進(jìn)位,如果小數(shù)部分不足,直接舍去小數(shù)部分,該算法代碼如下所示:
# 浮動(dòng)金額截取
def amountHandler(values, limit=2):
"""
@param values: 價(jià)格,單位: 分
@type values: int
@param limit: 小數(shù)點(diǎn)后2位
@type limit: int
"""
valStr = str(values)
length = len(valStr)
# 取到小數(shù)點(diǎn)的位置
dotIndex = length - limit
if dotIndex
realCount = limit - length
return '0.{}'.format('0'*realCount) + valStr.zfill(length)
# 整數(shù)部分后在插入小數(shù)點(diǎn),前面補(bǔ)'0'
integer = valStr[0:dotIndex].zfill(dotIndex)
decimal = valStr[dotIndex: length]
# 如果小數(shù)部分超出限制,直接向整數(shù)部分進(jìn)位
if len(decimal) > limit:
# 進(jìn)位
num = list(integer + decimal)
r = 0
for i in range(len(num) - 1, -1, -1):
tmp = int(num[i]) + r
if i == len(num) - 1:
tmp += 1
r = tmp // 10
num[i] = str(tmp % 10)
if r > 0:
num.insert(0, str(r))
integer = "".join(num[:-limit]) or "0"
decimal = "".join(num[-limit:])
else:
decimal = decimal.ljust(limit, '0')
return '{}.{}'.format(integer, decimal.lstrip('0'))
另外,在某些其他場(chǎng)景下,我們還可以通過(guò)Redis的位圖結(jié)構(gòu)(BitMap)進(jìn)行浮動(dòng)金額截取,具體實(shí)現(xiàn)如下所示:
# 浮動(dòng)金額截取,以位圖實(shí)現(xiàn)
def amountHandlerByBitMap(values, limit=2):
"""
@param values: 價(jià)格,單位: 分
@type values: int
@param limit: 小數(shù)點(diǎn)后2位
@type limit: int
"""
amount = values / (10 ** limit)
intValue = int(amount)
decimalValue = int((amount - intValue) * 10 ** limit)
bitMap = redis.bitmap(operation="getbit", key="amountBitmap", offset=limit-intValue)
# 如果這一位上是0,則表示沒(méi)有超過(guò)限制,直接置為1
if bitMap == 0:
redis.bitmap(operation="setbit", key="amountBitmap", offset=limit-intValue, is_overwrite=True)
if decimalValue > 0:
return str(intValue) + "." + str(decimalValue)
else:
return str(intValue)
無(wú)論何種實(shí)現(xiàn)方式,浮動(dòng)金額截取都是為了保證數(shù)據(jù)的準(zhǔn)確性和正確性,同時(shí)也能夠避免浮點(diǎn)計(jì)算的誤差累計(jì)問(wèn)題。而Redis作為一種高性能的內(nèi)存數(shù)據(jù)存儲(chǔ)系統(tǒng),其內(nèi)置數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)操作方式可以滿足上述要求,為金融交易系統(tǒng)等高并發(fā)場(chǎng)景下的浮動(dòng)金額截取提供了良好的支持。
香港服務(wù)器選創(chuàng)新互聯(lián),2H2G首月10元開通。
創(chuàng)新互聯(lián)(www.cdcxhl.com)互聯(lián)網(wǎng)服務(wù)提供商,擁有超過(guò)10年的服務(wù)器租用、服務(wù)器托管、云服務(wù)器、虛擬主機(jī)、網(wǎng)站系統(tǒng)開發(fā)經(jīng)驗(yàn)。專業(yè)提供云主機(jī)、虛擬主機(jī)、域名注冊(cè)、VPS主機(jī)、云服務(wù)器、香港云服務(wù)器、免備案服務(wù)器等。
網(wǎng)站題目:Redis中浮動(dòng)金額設(shè)置策略分析(redis浮動(dòng)金額設(shè)置)
文章源于:http://www.5511xx.com/article/cdsjeci.html


咨詢
建站咨詢
