bytedance / monoio

Rust async runtime based on io-uring.
Apache License 2.0
3.93k stars 223 forks source link

Sharding #213

Open likeabbas opened 1 year ago

likeabbas commented 1 year ago

Is your feature request related to a problem? Please describe. In many cases it would be good to shard a request to a particular based on some data within a server request. This would allow me to ensure any state related to that merchant can be processed on the same core/thread.

Here's a few scenarios where this would make sense

Describe the solution you'd like A similar implementation to sharing like glommio has https://github.com/DataDog/glommio/blob/master/examples/sharding.rs

Describe alternatives you've considered I haven't considered any

Additional context None

ihciah commented 11 months ago

I think it is a really useful thing, and it doesn't need to be binded with runtime itself. It can be used by users of all types of runtimes. If you are interested, you can write one based on tokio channel or async_channel. Maybe we can build it together?

likeabbas commented 10 months ago

I would love to work on it with you. Although I don't know what direction to take when you say you don't think sharding needs to be bound to the runtime itself. Could you expand on your thoughts on this, and maybe give some guidance on what you think this would look like?

I agree tokio_channel would probably make the most sense for the implementation. But I don't know what that would look like without the runtime having direct support for it.

ihciah commented 10 months ago

Some of my thoughts:

  1. It can be impl as multiple spsc channel.
  2. Each receiver may specify its capacity.
  3. The component allows user set lb strategy, like some consistent hashing parameters including hash method, ring size and virtual node count.
  4. Maybe receivers can join and leave at any time.
  5. If dest receiver's buffer is full, consider what strategy will be used.
Miaxos commented 9 months ago

I look forward this too, it would be really helpful.

I did not look into it yet, but would it be possible if instead of sharding with spsc, we have something like:

-> A TcpListener which accept a connection on one thread -> Accept it, wait for some data and peek over some data -> Find it's not the for this thread -> "Send" the fd to the proper thread which will be able to handle the whole connection without needing another accept

EDIT: If someone is looking, you should be able to build a lb strategy & a full mesh by using https://github.com/Miaxos/sharded-thread

Miaxos commented 9 months ago

This is what I had in mind, but it seems we are missing some implementation on monoio to be able to do something like that:

https://github.com/Miaxos/sharded-thread/blob/eb2d34bbe9ed81a906921729c9e3359ac7b347e4/tests/monoio.rs#L88-L187

It would need to pub some of the method of SharedFd and add a way to destroy it without running the close code which close the TcpStream. If you are ok with it, I'm going to have a try.

(ugly, but well, this is the idea)

likeabbas commented 9 months ago

@Miaxos that looks awesome!