parallel downloading of videos from several ip camras using java - java

I am building an application which downloads files from around 100 ip cameras paralelly over the network throught the day. The files in the camera are of length 1 minute varying around 1.5 to 2.5 Mb in size. Each of the files takes around 10 to 20 secs to download. The server I am using, has a four-core processeor with 8GB of RAM. The task is to download 1 file from each of the cameras per minute (60 files per hour) for 24x7.
First I tried by creaing as many threads as the number of cameras. This worked well for a relatively small number of cameras but as the numbers increased, I found that the number of files getting downloaded per camera is very less. Even in some days, the downloading is entirely missed for certain cameras. This I thought might be because I am creating one thread per camera, ie around 100 threads, some of the threads might not be getting the CPU at all. So I tried a second method.
I kept the number of threads same as that of the number of cores ie 4. So, all the cameras are handled by only four cores. This was done to ensure that the cameras are not getting missed. The code for this was done using the Executer class in Java handling a pool of four threads. As is the case, the files got downloaded from all the cameras. But now, the number of files getting downloaded per camera is very less. That is, in an hour, the server can download only around 15 files from each camera, while it is supposed to download 60 files in an hour (as each file is of duration one minute). This can be attributed to the fact that, each thread is handling 25 cameras, and the downloading performed by a particular thread is sequential. That is each thread will serially take up one of the 25 cameras and download from it before taking on the next. And each file takes around 15 secs on an average to get downloaded.
That network bandwidth is very high for the server but the network is slow in the camera side where it has got around 256 to 512 Kbps.
How should I optimize the code or the server config so as to download all the files from the camera. Moreover, the files in the camera are formed in real time, so I have go a single minute to download the files from all the cameras, otherwise, files will get skipped.

Related

Test Plan is not giving me accurate results

So I am wondering if someone can help me please, I am trying to load test a java rest application with thousands of requests per minute but something is a miss and I can't quite figure out what's happening.
I am executing the load test from my laptop (via terminal) and it's hitting a number of servers in AWS.
I am using the infinite loop function to fire in a lot of requests repeatedly. The 3 thread groups have the same config.
The problem I am having is the CPU is rising very high and the numbers do not match on what I have in production with the same enviornment with regards to CPU etc, the JMeter load test seems to be making the CPU work harder on my test enviorment.
Question 1 - Is my load test too fast for the server?
Question 2 - Is there a way to space out the load test so that I can say 10k rpm exactly?
Question 1 - Is my load test too fast for the server? - we don't know, if you see high CPU usage using 60 threads only and application responds slowly due to high CPU usage it looks like a bottleneck. Another question is the size of the machine, the number of processors and their frequency. So you need to find which function is consuming the CPU cycles using a profiler tool and look for the way to optimize the function
Question 2 - Is there a way to space out the load test so that I can say 10k rpm exactly? - it is, check out Constant Throughput Timer, but be aware of the next 2 facts:
Constant Throughput Timer can only pause the threads to limit JMeter's requests execution speed to the specified number of requests per minute. So you need to make sure to create sufficient number of threads in Thread Group(s) to produce the desired load, 60 might be not enough.
Application needs to be able to respond fast enough, i.e. 10000 requests per minute is approx 166 requests per second, with 60 threads it means that each thread needs to execute 2.7 requests per second which means that response time needs to be 370 ms or less
There are different aspects before we got for 10k requests.
Configure the tests for one user(/thread) and execute. Check for all
the request we are getting a proper response.
Incrementally increase the number of threads from 1 user, 5 users, 10 users, 20
users, 50 users etc.
Try for different duration scenarios like 10mins, 20 mins, 30 mins, 1 hour etc.
Collect metrics like error %, response time, number of request etc..
You can check probable breakpoints like:
CPU utilisaztion of machine getting high(100 %) from where you are executing the tests. in this case, you can setup few machines in master-slave configuration
error % getting high. Server may not be able to respond, so it might have crashed.
response time getting high. server may be getting busy due to the load.
Also, make sure, you have a reliable connectivity and bandwidth. Just imagine, you want to give a huge load, but the connection you have in few kbps. your tests will fail due to this.

Download files asynchronously through FTP in java

I need to download multiple files through FTP in java. For this I wrote a code using FTPClient which is taking files one by one to download.
I need to take files from a server and download to another network. After I wrote the code, I found that downloading is taking more time to download each file as the file sizes are huge (more than 10GB). I decided to multithread the process i.e. run multiple files at a time. Can anybody help writing me FTP in multithreaded environment.
Although I feel that multithreading won't help as bandwidth of the network would remain same and would be divided among multiple threads and leading to slow download again. Please suggest!!
You have different stuff to check first:
your download speed
remote server's upload speed
maximum server upload speed for each connection
If the server limits the transfer speed for a single file to a threshold lower than it's maximum transfer speed, you can have some advantages by using multi-threading (e.g. with a limit of 10 Kb/s per connection and a maximum upload of 100 Kb/s, you can theoretically have 10 downloads in parallel). If not, multi-threading will not help you.
Also if your download is saturated (all your bandwidth is filled with a single download or the server's upload bandwidth is greater than your download) you will not have any kind of help by multi-threading.
If your multi-threading will be useful, just instantiate a new connection for each file and throw it in a separated thread.
I feel that multithreading won't help as bandwidth of the network would remain same and would be divided among multiple threads and leading to slow download again.
That could well be true. Indeed, if you have too many threads trying to download files at the same time, you are likely to either overload the FTP server or cause network congestion. Both can result in a net decrease in the overall data rate.
The solution is to use a bounded thread pool for the download threads, and tune the pool size.
It is also a good idea to reuse connections where possible, since creating a connection and authenticating the user take time ... and CPU resources at both ends.

Java consuming too much memory

I have a java app. Its use is to automate login to websites and create wifi hotspots. It is a GUI app with many features such as a notification manager and system tray. My JAR file has a size of 3 MB but, it consumes about 100 MB of RAM. Should I be worried?
I checked if any of my methods were recursive and I could not find any.
My java app's code can be found here : https://github.com/mavrk/bitm-cyberoam-client/tree/master/JavaApplication13
A one line program can use 8 GB of memory.
If you are concerned about the size of the heap you can either
reduce it further, though this might slow the application or prevent it from working.
use a memory profiler to see where the memory is being utilised.
not worry about about 50 cents worth of memory. If you are minimum wage you shouldn't spend more then 6 minutes on it or your time will be worth more than the memory you save.

Android 3g downloads and multiple threads

If you have 10 tasks, and each one takes 5 seconds to download, so 50 seconds total, would you be able to accomplish the task quicker by running 10 parallel threads and downloading all 10 at once?
I think it would take slower, but I don't really know.
Would this hold true of Android? Would running 10 parallel downloads be faster then running them in a single priority queue?
edit: if it matters I'm seeing a average .20 Mbps - .50 Mbps average in the locations where the downloads would likely take place.
It depends where the bottleneck is.
If you're downloading from 10 different servers and they're all serving up the data relatively slowly, it's possible you have enough bandwidth on the device to download from all 10 (or at least some number greater than one) at the same time, in which case multiple threads will be faster.
However, if a single download from one server is already enough to use up all of your bandwidth, then 10 at the same time isn't going to be any faster. And the extra overhead and contention for resources will likely make it slower.

Java/Scala resource consumption and load

I am developing a web application in Scala. Its a simple application which will take data on a port from clients (JSON or ProtoBufs) and do some computation using a database server and then reply the client with a JSON / Protobuf object.
Its not a very heavy application. 1000 lines of code max. It will create a thread on every client request. The time it takes right now between getting the request and replying back is between 20 - 40ms.
I need an advice on what kind of hardware / setup should i use to serve 3000+ such requests per second. I need to procure hardware to put at my data center.
Anybody who has some experience deploying java apps at scale, please advice. Should i use one big box with 2 - 4 Xeon 5500s with 32 GB RAMs or multiple smaller machines.
UPDATE - we dont have many clients. 3 - 4 of them. Requests will be from these 3 of them.
If each request takes on average 30 ms, a single core can handle only 30 requests per second. Supposing that your app scales linearly (the best scenario you can expect), then you will need at least 100 cores to reach 3000 req/s. Which is more than 2-4 Xeon.
Worst, if you app relies on IO or on DB (like most useful applications), you will get a sublinear scaling and you may need a lot more...
So the first thing to do is to analyze and optimize the application. Here are a few tips:
Creating a thread is expensive, try to create a limited number of threads and reuse them among requests (in java see ExecutorService for example).
If you app is IO-intensive: try to reduce IO calls as much a possible, using a cache in memory and give a try to non-blocking IO.
If you app is dependent of a database, consider caching and try a distributed solution if possible.

Categories