Event driven networking interfaces for module system#4158
Event driven networking interfaces for module system#4158sunxiaoguang wants to merge 1 commit intoredis:unstablefrom
Conversation
|
More comment on this: The reason behind all the new interfaces being added comes from another project I'm doing which use something similar to php-fpm to write module business logic outside of redis-server process. Being able to run logic externally adds these benefits:
With these new interface, some more interesting modules can be developed. For example, we can use nonblocking MySQL c api to connect redis-server with an mysql server, use redis as L1 cache and if cache misses reload the data from mysql server. This can simplify the typical web development task where people normally need to write cache management code to check redis for cached data and if it's missed, reload data from mysql and cache the response in redis. Now all these can be implemented in nonblocking way at a single place with the high performance event loop that already exists inside redis-server. |
|
Thanks for @badboy labeling this pull request, I will put more design and proposal later on this thread. |
Proposed Features:Event Loop:Export redis server event loop to module and execute a callback function when a specific event occurs on a file descriptor or a scheduled timeout has been reached. Networking:Export socket related utility functions to module to make writing portable socket code easier. Client:Nonblocking connect which is required to not block redis server when connection has to be made in the middle of dispatching a command. Both Tcp and Unix addresses are supported. Server:Support writing Server using TCP over IPv4 and IPv6 or Unix domain socket Socket options:Misc. important options related to socket programing. Misc. socket functions:Utility:Context:Module can attach some context data which can be stored and accessed with key anywhere a RedisModuleCtx is available. An optional destructor callback function can be setup at each attachment basis and will be called with RedisModuleCtx and the attachment itself as arguments when the attachment is detached explicitly or implicitly by ether new RedisModule_Attach call with the same key or unloading module without detaching first. In addition, there is a special attachment called the default one when the key of the attachment is NULL and length of key is 0, it can be accessed directly without hash lookup compared to normal attachment. Redis Client:Directly connected client to redis server. The returned client file descriptor can be used to interact with redis server. |
Use case scenarios:Module with IO:Sometime, there is need to initiate IO requests to external system. Since IO request usually takes nondeterministic time to finish or timeout eventually, either extra thread or IO multiplexing is required to execute the request asynchronously without blocking the command dispatching thread, the redis sever thread in this case. Since multithread incurs more cost than IO multiplexing, using event driven approach is important for performance critical applications. With Event Loop and Networking Interfaces, people can implement such application efficiently using high performance redis server event loop with minimum overhead. Some widely used software have nonblocking API which can be hooked into event loop directly, for example MariaDB's Non-Blocking MySQL Client Library and hiredis async client. Even if no such client is available, a hand written client using socket API directly can be implemented if the protocol is clear and easy to write. Embed redis as caching layer:For server applications that need caching large amount of data, writing a fast, reliable and feature rich caching layer isn't trivial. Redis satisfies all the requirements and can be a perfect caching layer of such applications, however deploying a separate redis server adds complexity of deployment. In addition, application need to worry about cases such as reconnecting if connection is broken or handling doubtable failure when connection is broken in the middle of executing commands. Even if all such cases are handled carefully, network latency is inevitable due to physical limitations. Embedding redis directly can get around many issues on the other hand. I tried to patch and rebuild redis-server itself as an shared library to do such embedding before module system came out. Now, With module system, I can move all my server's logic into a redis module, and let redis-server host my code which is reasonable and works perfectly. With the server interface exported, I can even let my module start a server and let the same original client to use the original protocol to talk to my server, yet still being able to talk to the hosting redis server easily. If the server starts other threads, using the direct connected client's file descriptor to talk to hosting redis server can make multi threaded programming a lot easier, and don't even need to bother locking and if a module function is not thread safe and must be called on behalf of redis server event thread. |
|
@badboy I have posted some more comments about the proposed features and two use case scenarios related to the proposal. Looking forward to hear comments from you. Thanks. |
f0cb7e6 to
e2689d0
Compare
e2689d0 to
820c6ef
Compare
|
Published a module (rpm) that uses these new interfaces to write module in external process. A golang framework for writing such module process is included. |
820c6ef to
31c4532
Compare
Export event loop and certain networking related interfaces to module. A demonstration module 'hellonet.c' is added to demonstrate how to use these new set of module interfaces to write event driven commands without resorting to extra thread.
31c4532 to
cbb3657
Compare
|
|
Export event loop and certain networking related interfaces to module. A
demonstration module 'hellonet.c' is added to demonstrate how to use these new
set of module interfaces to write event driven commands without resorting to
extra thread.