tidwall / evio

Fast event-loop networking for Go
MIT License
5.9k stars 493 forks source link

Using splice system call for even better performance #12

Open janflyborg opened 7 years ago

janflyborg commented 7 years ago

HAProxy (and probably also Redis) is using the system call splice in Linux (http://man7.org/linux/man-pages/man2/splice.2.html) in order to copy data from one file descriptor to another.

This means that it efficiently implements proxying functionality, since it does not have to copy data from the kernel to user space and then back to the kernel.

The pattern of letting the callback evio.Events.Data always perform a copy in user space, will always be somewhat slower than what HAProxy can achieve, so is this something you have thought about for evio?

diegobernardes commented 6 years ago

The proposal to add splice at the std lib was accepted: https://github.com/golang/go/issues/10948. There is also a prototype of it: https://github.com/golang/go/compare/master...philhofer:net-splice

Adding splice to evio would be very nice too, @janflyborg is right, you can't really compete with HAProxy without this.

tidwall commented 6 years ago

@janflyborg

Thanks for the suggestion. It's not something I've put much thought into yet (but I should). I've been mostly focused on data translations at the protocol layer, such as gRPC to Redis and fan-in packet pipelining. Stuff that needs to be done in user space.

I could be wrong but I don't think Redis uses splice. Likely because data must be read off the wire into user space to be parsed. Right now I'm seeing equivalent performance of evio and Redis.

As for direct byte-to-byte proxies, I absolutely see how using splice would benefit performance. I'm always happy to leave any operation that I can up to the kernel. Not sure how I would implement it yet in the evio API... 🤔 I'll figure something out.

@diegobernardes

Thanks for the very helpful links. It appears that Go has a syscall.Splice operation that I can use. That's a plus!

janflyborg commented 6 years ago

Thanks for the answers @diegobernardes and @tidwall. That sounds really good. Evio is just what I have been looking for and even if I have not used it yet, it seems like a perfect fit for some of the use cases I encounter from day to day. Zero-copy is impossible to achieve when you have to transform or inspect the data, so you are probably correct that Redis does not use splice.

I have looked at philhofer's patch for the stdlib and since it is deeply tied to the rest of the library, I'm not sure if it will help you here, but the syscall is (as you said) at least available.

ghost commented 5 years ago

any development with this?