bavix / laravel-wallet

It's easy to work with a virtual wallet
https://bavix.github.io/laravel-wallet/
MIT License
1.12k stars 223 forks source link

Improving performance, Facing race conditions #898

Closed kambadprashant closed 6 months ago

kambadprashant commented 6 months ago

Hi, Getting across this package and it’s awesome, have been using it in one project already and it’s working fine.

Currently using it in another project which has very high number of transactions, almost reaching 50 TPS for one wallet, up to 10 TPS is fine but after that even using 3 Sec TTL for lock, I am getting LockTimeoutException.

I am using redis for lock and cache driver.

I have also looked into High performance API but it’s also not very effective because I will not have an array of wallets because in every request, system will only process one transaction.

The only option I see here is to decrees the time required for one transaction to complete but I thing it’s already optimised, another option I think is to maintain balance in cache only and only update in DB every second or so, but I want to know your opinion on what is the best way to get this working.

Thanks for your good work!

rez1dent3 commented 6 months ago

Hello.

I am using redis for lock and cache driver.

Redis is single-threaded, you have a queue and some requests fall off due to timeout, which is logical.

It is necessary to switch to processing through queues. For example, use the Kafka broker + custom partitioner strategy. Then you process inside the partition by wallet in the correct order (Kafka guarantees) + redis locks.

High-performance API, as you correctly noted, is only for huge batches.


Another important point is that if you have an old version of the package, it’s worth updating. Versions 7 and 8 of the package are much inferior to the latest versions.

Name 7.3 8.4 9.6 10.1 11.0-dev
Atomic:Blocks - - 484ms 493ms 493ms
Cart:EagerLoaderPay 22s 679ms 493ms 530ms 652ms
Cart:Pay 1.36s 472ms 288ms 298ms 336ms
Cart:PayFree 1.3s 415ms 281ms 291ms 287ms
Cart:PayOneItemXPieces 565ms 118ms 59.1ms 64.6ms 66.2ms
Gift:Gift 44.8ms 53.5ms 54.3ms 58.4ms 64.3ms
Gift:Refund 106ms 112ms 108ms 111ms 139ms
Solo:Deposit 27.4ms 31.8ms 31ms 33.3ms 30.1ms
Solo:EagerLoading 904ms 1.09s 876ms 927ms 1.02s
Solo:ForceWithdraw 27.6ms 31.8ms 30.7ms 32.9ms 30ms
Solo:GetBalance 20.8ms 24ms 23.7ms 23.4ms 20ms
Solo:Transfer 39.4ms 45.7ms 42ms 44.9ms 46.6ms
Solo:Withdraw 31.1ms 36.3ms 34.9ms 37.3ms 37.8ms
State:InTransaction 570ms 566ms 419ms 425ms 427ms
State:RefreshInTransaction 32.3ms 41.2ms 41.2ms 45.6ms 47.2ms
State:TransactionRollback 29.7ms 34.1ms 32.9ms 37.2ms 36.9ms

In general, I advise you to look at what specifically is slowing you down. You need to add metrics to your service.

I don’t know anything about your transactions, but it might be easier to add hardware to the database.

rez1dent3 commented 6 months ago

after that even using 3 Sec TTL for lock

PS, 3 seconds is a lot

kambadprashant commented 6 months ago

Hi, Thanks for your reply, That was fast!

Yes, I had considered to use queuing system of some kind but kafka was not in mind, Have already looked into it and it seems promising enough, Will try that out.

Also, as suggested will also look deeper into my project to see if I can pinpoint something that's slowing down the processing and can optimize it as well.

Thanks again!

Will update once I find the solution for this.

PS, Yes 3 seconds is a lot and will definitely reduce it :)

rez1dent3 commented 6 months ago

I think I'll close the issue for now. If necessary, recreate issue.