Comments (4)
To clarify the issue, it sounds like:
- You have 3 replicas of pods that contain/use golongpoll
- You are having a request to subscribe to category
someCategory
, which gets load balanced/routed to podB
- You have another request to publish on
someCategory
, which gets load balanced/routed to PodA
- Because the pub/sub calls are hitting different pods/replicas, they're not aware of each other and your subscription request will never see the published data.
Is this what's going on?
That would be expected, as the longpoll manager is stateful, and does not auto-magically sync with other instances.
I'd have to think long about ways to make cross-replica state syncing work, as this was never part of the design. However, there is a relatively simple way to scale longpolling pub/sub if you can load balance/route requests based on the category. This would involve sharding the categories. For example:
- Requests to pub/sub on given Category
C
deterministically get routed/load-balanced to a longpoll instance/container based on the hash/modulo of the category. - Because a given category's data always winds up on the same instance, you can scale as large as you like with the caveat that a single category must be contained on a single instance, but each instance would have only 1/N categories where N is the number of replicas.
- Ex: take hash of category and modulo N where N is number of replicas and route traffic accordingly. This would be easier of the category that is in the pub/sub request is baked in to the URL.
One final thing to be aware of if going the sharding route: if you increased/decreased the number of replicas, then you would stop seeing some category data as traffic would start gettign sharded differently.
from golongpoll.
I have learned your response and thanks for resolving my confuse.But it seems difficult to fix this for a service in k8s,cause this service may have HPA or something.Is there any possibility to use some distributed databases like Redis to resolve this gently?
from golongpoll.
You are right, having horizontal auto scaling would break any attempt at sharding traffic based on category because: 1) we'd have to update the shard size/update how load balancing works and 2) any state before the scale change would be now sharded incorrectly.
Could something like redis pub/sub be used to solve this? Maybe.
I've been thinking of making a more k8s-ready longpoll library, and something like Redis for the data may be a solution. But this would be a new library, as this would not easily fit within the existing design.
As a future note to myself in the event I start working on a new library:
https://thenewstack.io/redis-pub-sub-vs-apache-kafka
The article says redis pub sub will only send data to connected/subscribed clients--if they're not connected, they miss out. So for implementing reliable pub sub via longpoll + redis backend, the longpoll plumbing would have to keep the go-->redis subscriptions alive even after a client's longpoll subscription returns data. Otherwise, if we only have go-->redis subscriptions up while a longpoll request is waiting for data, when golongpoll returns data to the client and the http request disconnects, we'd miss out on any redis data between the time we return and when the http client re-requests the next longpoll.
So it sounds initially like we'd have to keep redis subscriptions alive for a configured amount of extra time and reuse the connections for multiple longpoll requests on the same category.
Ah ha! We're back to the same problem--if we have to keep redis subscriptions alive between longpoll requests otherwise we miss out on reids data, then we're back to the orignal problem of having to always get load balanced to the same longpoll node, as getting routed to a different one that wasn't already listening on a given redis channel would be missing out on recent data. This solution does get around having to "rebalance" sharded data as we're relying on redis for data, but we still would need "sticky" connections in that they'd always have to go to the same longpoll node for a given category.
So now I wonder if some other messaging layer like kafka is how one would address this.
Thinking about this more... maybe there's still a way with redis. My uncertainty comes from not having actually used redis before...
If we can use redis pub sub to get new events, but rely on a more traditional query to get recent past events since a given time, then this might be able to work. Something like:
Longpoll request received for category X:
- see if any redis data for X since time T, if so return longpoll data.
- else, subscribe on X for new data, return data or timeout within time window..
the above may work, as long as we handle the corner case of data coming in after the query and before the redis subscription. One may have to always subscribe first, then do the redis query--which sounds more costly, but gets around the timing issue.
The above idea sounds like it would get around HPA issues since: 1) redis has the state, the longpoll nodes dont' need to maintain or shard any. 2) because stateless, it doesn't matter which longpoll node an http client winds up on.
I'll think about the above some more, and if it sounds good I may try a golongpoll-redis type library that plays nice with k8s + HPA.
Thanks for the issue feedback.
from golongpoll.
Making longpoll-server stateless and use another stateful database like redis(or other one) behind.
Thanks a lot
from golongpoll.
Related Issues (20)
- add data backend for scaling and data persistence support HOT 2
- Listen on multiple categories HOT 1
- Do you have an example on how to create a reliable http client to consume golongpoll?
- Offer an "official" Golang client HOT 2
- High CPU load? HOT 5
- client js HOT 3
- Events published in same millisecond aren't seen by clients HOT 3
- Please replace deprecated CloseNotify with Context().Done() HOT 3
- question: version migration guide HOT 2
- How do you make sure the concurrent issue? HOT 2
- Gin framework support HOT 7
- Acks every 15 seconds HOT 1
- hi,how to custom SubscriptionHandler and PublishHandler ?
- Go Mistake #76: time.After and memory leaks
- Handler keeps on waiting for a timeout even though the client has been disconnected. HOT 5
- question about Http Server integration HOT 5
- Latest tag name seems like a typo - messes up SemVer HOT 2
- used in production? HOT 1
- Example of scaling this ? HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from golongpoll.