-
Notifications
You must be signed in to change notification settings - Fork 65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rserve for real-time performance tips #64
Comments
Q: Could the performance degenerate over the time? Q: Is a good practice to share the session among consecutive requests? Q: Is a good approach to use Rserve for this real-time service? |
Thanks so much for the clear response |
Complimenting this thread: got exactly the same use case as @alvsanand but RServe doesn't seem to be performing well as stated. If I go higher than 4 requests/second, RServe basically hangs. I am by no means an expert in R, so I can be doing something wrong, but I wanted your opinion. I have a randomForest model that I run behind a Rserve. I send data as json string to it through the java client and when the data is converted to proper R structure using jsonlite The first time I ran this code, So my questions are:
|
First, this is really an R question, not Rserve question. Rserve itself has a very small overhead (more below) so all the time spent is purely related to R and your code. It's really impossible to give you precise answer due to lack of details (e.g., there are at least three different packages implementing Second, Rserve can easily handle hundreds of connections, we use it routinely that way and it had been tested in many big companies. So the real question is what is your R code and waht resources are you using? Again, regular R rules apply, it has nothing to do with Rserve itself. If you use R at 100% CPU and have only 4 cores then obviously, they get saturated at 4 connections. So profile your R code (unrelated to Rserve) and that will give you the estimate of expected performance. In practice, the user R code takes the vast majority of compute time, so Rserve's overhead is negligible. However, there are very special cases if you use very fast scripts (we're talking single-digit milliseconds). On a typical server machine the forking overhead of a connection is in the order of 3ms. After that each connection is an independent process, so you're only bound by the number of cores you have. However, the first 3ms are serial as the forking comes from the server process, so you have an effectively limited rate of ~30 new connections per second (note: that doesn't limit the number of parallel connections). If that is not enough, you can use the |
thanks for the quick response simon. I thought it was probably somethingto R code, but I wanted to make sure. I was using the
I found the email list, so I sent there a more detailed version of this question. |
I have a similar problem related to near-real-time predictions as stated in this thread and stated here. I am running a Java application which contacts the RServer to score some data. I want to do this near-real-time. If I am using a 1 thread java application to send sequential requests to 1 Rserve instance, I am achieving an average response time between 5 and 6 ms. If I now increase the Java threads, thus increasing the requests and also simulating parallel requests, the performance trops significantly to 25ms per request. Is this expected due to request handeling or did I configure somthing wrong at the server? I also tried to manually increase the number of Rserver instances with different ports, but the results are the same. Is there a better solution for my intentions? |
What is exactly your setup? The fixed cost I mentioned above is associated with the fork-on connect, i.e., if you create multiple I did some testing and I cannot replicate any issues related to parallel connection. With a simple test that merely does
and eventually it settles around 40µs. The numbers don't change as I'm increasing the number of parallel connections until you start saturating all the cores (it started getting close to saturation at 12 parallel connections on a 16 core (32HT) machine when the 40µs were slowly rising toward 50µs). Note that This suggests that Rserve itself has very minimal overhead if used over an existing connection (40µs are really negligible compared to any actual work in R), so everything really depends on the R code. The relatively expensive first Also I would expect the numbers to be lower if you use C since there is quite a bit of Java overhead involved as well, but I didn't run that test. Finally, Java cannot use unix sockets, so I suspect the reason why the initial connect is closer to 10ms is probably due to Java, not Rserve, since the typical fork cost on that machine is below 4ms. The Java code:
I conducted the test on Ubuntu 14.04.3 LTS (Linux 3.13.0), Rserve 1.8-5 (one instance running on loopback TCP/IP), R 3.2.3, Oracle Java 1.8.0_101, 2 x E5-2667 v2 @ 3.30GHz PS: Just to clarify, the suggestion for low-latency jobs to use multiple Rserve instances is not meant one instance per connection as every instance has the same connect cost, but it is intended to spread the serial fork cost across multiple cores, so it really only makes sense for servers with many cores (let's if you have one server instance maxed at 15 conn/s, then with two you'll have 30 conn/s, with 4 you'll get 60 conn/s etc. - but you must leave room for the actual R code CPU usage as well so you typically want at least twice as many cores as you have instances - in most cases even more). |
Thank you for taking the time and looking into this :) I am with you with the forking and I think I understood that. To clarify: I am setting up a connection to the Rserver as you do. Then I am iterating over a json list which I parse and evaluate in R. My list contains 500 Json strings. In R I am transforming the string into a dataframe and then use a preloaded model to score it. The result is returned. Its a 3 liner in R and if I preload everything in R, it scores very fast < 1 ms. Printing out the processing results for this example in ms: [23.8396], [11.590236], [7.09057], [6.886749], [6.90031], [7.266447], [5.715192], ... It stablizes at about 5 ms with some outliers reaching up to 10 and going down to 3 ms. Processing all 500 Strings takes about 3083 ms ~ 3 sek. Very good results and thats how I want them. (ping is about 1 ms and probably explains some of the variance) However, I am performing each scoring in a sequential order. This is a limitation which I would like to overcome. Thus, I wanted to test the performance when increasing the incoming requests by putting them in parallel. In the results above I am using 1 Java Thread iterating sequentially over the json list. Therfore, I suspect that Rserve only uses 1 CPU Core during the 3 sek runtime. (Max. 2 while forking the Connection in the beginning) Is this correct? At least that is what I suspect from my Java evalutation statment. It waits until the results are given back, then sending the next json string with the next eval statment. I simply added another thread doing the same thing. Connecting to Rserve and then iterating sequentially over the json list. For this test I only took 250 json strings for each of the threads to see how they compare to the solution with 1 thread. The results are worse: Thread 1: [36.647827], [39.746638], [41.766351], [12.736725], [28.635956], [29.959145], [17.718], Total preocessing time: 6,5 sek. I expected the time to be close to 2 sek. I don't really know what is happening here. Is my suggestion, that Rserve only utilzes 1 Core while answering the sequential requests, simply wrong? I can also provide you with the java + R code if you would like to. System: CentOS release 6.7 (Final), Rserve 1.8.5, R version 3.2.2, Java 1.8.0_101, 1x Intel(R) Xeon(R) CPU E3-1230 V2 @ 3.30GHz Again thank you for helping me! |
R is always sequential, it doesn't support threading. If you want parallelism, you have to open multiple connections and use them in parallel, Rserve supports that. |
I am developing a REST service that uses a Machine Learning model of R. This service will be used by a web page of well-known company, so the traffic will be a high and it must be a 24/7 service. My idea is to use the RServe to calculate the predictions based of the model using R. Although I have played some time with RServe sharing the connection among consecutive requests, I have some doubts:
The text was updated successfully, but these errors were encountered: