I'm interested in assigning different workloads to each worker of a particular type in Heroku. The workload is continuous rather than discrete so a work queue is not appropriate. I could coordinate work through a database or Zookeeper, but these bring complexity and reliability issues.
I know that Heroku dynos are assigned names like worker.1 but I'm curious how these names are assigned and if I can rely on them to have certain properties. I'm only interested in the behavior for worker dynos since web preboot probably changes the behavior for web dynos.
Specifically,
Is it possible for two dynos to have the same name/number at the same time (I assume not for worker processes since the previous one should be shutdown or have failed before a new one is started)
If the ps:scale for my worker is n, can I rely on dyno names being worker.1, worker.2 ... worker.n or would I sometimes get numbers outside (1, n)? If it is possible to get numbers outside (1, n) under what circumstances might it happen?
I'm hoping to create a configuration that maps worker numbers to work assignments so I would rely on worker numbers to be exactly 1 to n.
Related
We are using HireFire to manage multiple DelayedJob queues, with queues associated with different Procfile entries that might vary by application.
For 95% of the day some of the dyno types in the formation are scaled to 0. (Basically, overnight batch jobs start, submit to one queue or other, and Performance-M or L dynos are scaled to 1, 2, or 3 to handle the jobs, then they scale back to zero when the queues are empty).
The CLI ps command will retrieve information on the running processes, but if one or more of the dyno types is scaled to zero, they do not appear.
Does anyone know of a way of retrieving dyno formation info even when the dynos are not running?
I am looking for the best approach to handle the following scenario:
I have multiple edge devices publishing sensor data to a RabbitMq broker. The broker will experience an overall workload of ~500 messages per seconds. Then there is a python worker dyno who consumes one sensor reading at a time, applies a filter on it (which can take up to 5-15ms) and publishes the result to another topic.
Of course one worker is not enough to serve all requests, so I need a proper scaling. I use a queue to make sure each sensor reading is consumed only once!
My questions are:
Do I scale horizontally and just start as many dynos as necessary to handle all requests in the RabbitMQ queue? Seems simple but more expensive.
Or would it be better to have less dynos but more threads running on each dyno, and using e.g. celery?
Or is there a load balancer that consumes 1 item out of the queue and schedules a dyno dynamically?
Something totally different?
option 1 or 2 are your best bets
i don't think option 3 exists without tying directly into the heroku API, and writing a ton of code for yourself... but that is overkill for your needs, IMO
between 1 & 2, the choice would depend on whether or not you want to grow the ability to handle more messages without re-deploying your code.
option 1 is generally my preference because i can just add a new dyno instance and be done. takes 10 seconds.
option 2 might work if you don't mind adjusting your code and redeploying. it will add extra time and effort for the tradeoff of cost.
but at some point, option 2 will need to turn into option 1 anyways, as you can only do so much work on a dyno to begin with. you will run into limitations on threads, with dynos. and then you'll be scaling out with dynos.
It seems with GuvScale you can scale the workers consuming massages from RabbitMQ
Heroku describes their dynos here and it lists the amount of memory each one has and also the amount of Compute resources. Nowhere do I see the definition of a "Compute".
When I run this command on the performance-l dynos it tells me it has 8 cores.
grep -c processor /proc/cpuinfo
I don't see how this relates to the 46x Compute that's on the chart. It seems like an arbitrary number to me and I don't understand exactly what it is.
Heroku's compute units are just Amazon's compute units (because Heroku runs on top of AWS).
One compute unit on AWS is defined as the computer power of a 1.0-1.2Ghz of a 2007 server CPU.
Keep in mind though: these units are typically pretty variable depending on how many other active dynos are on the same underlying EC2 host.
The Appharbor pricing page defines a worker something you increase to "Improve the reliability and responsiveness of your website". But in trying to compare price with others such as aws, I am having a hard time defining what a worker is exactly.
Anyone have a better definition than "more is better"?
From this thread:
AppHarbor is a multitenant platform and we're running multiple
application on each application server. A worker is an actual worker
process that is limited in terms of the amount of resources it can
consume.
...
2 workers will always be on two different machines. We're probably
going to reuse machines when you scale to more than that and increase
process limits instead (this could yield better performance as you
need to populate fewer local cache etc.)
I have some matrix multiplication operation. I want to parallelize the execution of those operations through multiple processors.. This can be done on high performance computing cluster using MPI (Message Passing Interface).
Like wise, can I do some parallelization in the cloud using multiple worker roles. Is there any means for doing that.
The June release of the Azure SDK and Tools, version 1.2, now supports .NET 4. You can now take advantage of the parallel extensions included with .NET 4. This includes Parallel.ForEach() and Parallel.For(), as examples.
The Task Parallel Library (TPL) will only help you on a single VM - it's not going to help divide your work across multiple VMs. So if you set up, say, a 2-, 4-, or 8-core VM, you should really see significant performance gains with parallel execution.
Now: if you wanted to divide work up across instances, you'll need to create a way of assigning work to each instance. For example: set up one worker role as a coordinator vm, and another worker role, with n instances, as the computation vm. Then, have the coordinator vm enumerate all instances of the computation vm and divide up work n ways. Send send 1/n work messages to each instance over WCF calls over an internal endpoint. Each vm instance processes each work message (potentially with the TPL as well) and stores its result in either blob or table storage, accessible to all instances.
In addition to message passing, Azure Queues are perfect for this situation as each worker role can read from the queue for work to be performed rather than dealing with iteration. This is a much less brittle approach as the number of workers may be changing dynamically as you scale.