Search code examples
.netdistributedcomputationorleans

Using Orleans, how to implement distributed computation with distributed data storage?


I am new to distributed computation and orleans, recently do some research on those,and not sure whether orleans can be used for new task.

This task is that, there are many projects belong to different people and each project has a lot of data. For each project, the steps like below:

  1. Get new data via calculating raw data.Raw data is stored in distributed database, and then new data will be stored back to database. MQ or Redis may be used to improve performance.
  2. Calculate summary values from new data and save summary value back to database.

My questions are:

  1. Server/Grain Load Balancing: Grans without unique id. It is better to run many grains in all servers for load balance, each grains just get data from database and do computation, no need to create a instance with id. For Orleans, it is not allowed for grains without unique id except stateless grains, and stateless grains just run locally.
  2. Long Run Computation: The calculation and summary may take several seconds or minutes to finish work, Is it recommended to using grains? seem it is not recommended in document.
  3. Sequential Execution: It is necessary that calculating new values from raw data first, and then summary based on new values. It means that grains for summary must be run after all of grains for calculation are done.
  4. Data Caching: Grains get Data from and save data to database via local network, Are there any suggestion for orleans to reduce data transfer?

Solution

    1. Server/Grain Load Balancing: The stateless worker grains work well for automatic scale-out. As noted, the calls will be routed to grains on the current silo (or to the gateway silo if the call originates from a client). For long-running tasks, scale-out is effectively limited to a number of grains that matches the number of CPU cores. However, it sounds like you can/want to control the scale-out. I would suggest routing to your own "stateless" grains using Guid.NewGuid(). Alternatively, look at publishing work to a stream. The stream events will be pulled by different agents on all silos and processed across the cluster.
    2. Long Run Computation: It depends on the specifics of your work and code, but in general I do not think Orleans "turns" are a good fit for long-running tasks. The Orleans execution model gives you one thread per CPU core in your cluster. Other grain calls may begin to fail/timeout if your Orleans threads are all locked to long-running grain calls. You could work around that issue by breaking your long-running task into smaller chunks. Alternatively, you could run your long-running task in a separate thread (see External Tasks and Grains). Be sure to look at adjusting the default grain call timeouts if needed.
    3. Sequential Execution: You can have the grains that calculate values from your raw data send a notification when the job is complete to the grain that calculates the summary. If your summary can/should be calculated incrementally, then simply calculate the summary on each notification. However, if you need to wait for all jobs to complete, then simply have the grain that calculates the summary keep track of which are still pending. Then, only calculate the summary once all of the notifications have been received.
    4. Data Caching: You can cache data in a grain instance variable. This often reduces the number of database calls needed as subsequent grain calls will route to the same activation for a period of time (until it goes idle and deactivates).