Dapr status management

Keywords: Dapr

preface:

In the previous article, we learned about the service invocation mode of Dapr. In this article, we continue to learn about state management.

1, Status management - problems solved

Tracking status in distributed applications has the following problems:

  • Applications may require different types of data storage.
  • Different levels of consistency may be required when accessing and updating data.
  • Multiple users can update data at the same time, which requires conflict resolution.
  • When interacting with the data store, the service must retry any transient errors that occur  .

The Dapr state management building block addresses these challenges. It simplifies tracking states without dependencies or third-party storage of learning curves on Sdk.

Dapr status management provides   Key / value   API. This feature does not support relational or graphical data stores.

2, State management - how it works

Applications can use Dapr's State Management API to save and read key / value pairs using state storage components. Call the API via HTTP or gRPC.  

 

For example, you can save a key / value pair by using HTTP POST, and you can read a key and return its value by using HTTP GET.

 

3, Status management - features

  • Pluggable state storage

The Dapr data store is modeled as a component that can be replaced without modifying your service code.

  • uniformity

   CAP theorem Is a set of principles applicable to distributed systems that store state. The following figure shows the three properties of CAP theorem.

  

The theorem points out that distributed data systems provide a trade-off between consistency, availability and partition tolerance. Moreover, any data store can only   Ensure two of the three properties:

    • uniformity   (C) . Each node in the cluster will respond with the latest data, and the system must block the request even before all replicas are updated. If you query the consistency system for the item currently being updated, you will not receive a response until all copies are successfully updated. However, you will always receive the latest data.

    • usability   ()  . Even if the response is not the latest data, each node will return an immediate response. If you query the item being updated in available systems, you will get the best possible answer that the service can provide at this time.

    • Zone tolerance   (P) . Even if the replicated data node fails or loses the connection with other replicated data nodes, the system can continue to operate.

Distributed applications must handle   P   Properties. With the network call communication between services, a network interruption (P) occurs. With this in mind, distributed applications must be   AP   or   CP.

  AP   Select availability consistency for the application. Dapr through its   Final consistency   Policy supports this selection. Please consider using basic data storage (such as Azure CosmosDB) to store redundant data on multiple replicas. For final consistency, the state store writes the update to a copy and completes the write request with the client. After this time, the storage updates its copy asynchronously. A read request can return data for any copy, including a copy that has not yet received the latest update.

  CP   Application selection consistency and availability. Dapr through its   Strong consistency   Policy supports this selection. In this scenario, the status store is updated synchronously   All   (or, in some cases, after completing the write request)   Previous) required copies   Arbitration. Read operations continuously return the latest data across replicas.

  • Concurrent

  In multi-user applications, it is possible for multiple users to update the same data at the same time. Dapr supports optimistic concurrency control (OCC) To manage conflicts. OCC is based on the assumption that update conflicts are rare because users process different parts of data. A more effective way is to successfully update and retry if unsuccessful. An alternative method to implement pessimistic locking may affect long-running locking and lead to data contention.

Dapr supports ETag) (optimistic concurrency control of OCC. ETag is a value associated with a specific version of the stored key / value pair. The ETag value is also updated each time the key / value pair is updated. When the client retrieves the key / value pair, the response includes the current ETag value. When the client updates or deletes the key / value pair, it must send back the ETag value in the request body. If other clients update the number of keys at the same time According to, the ETag will not match and the request will fail. At this time, the client must retrieve the updated data, make changes again, and then resubmit the update. This policy is called   Write - wins for the first time.

Dapr also supports   Last write wins   Policy. When using this method, clients do not attach etags to write requests. The state storage component will always allow updates, even if the underlying value has changed during the session. Finally, write wins is very useful for high-throughput write schemes with less data contention. Similarly, occasional user updates can be tolerated.

  • affair

  Dapr can   Multiple changes   Writes to the data store as an operation implemented as a transaction. This feature is only available for supported   ACID   Transaction data storage. At the time of writing this article, these stores include Redis, MongoDB, PostgreSQL, SQL Server and Azure CosmosDB.

In the following example, multiple operations are sent to the state store in a single transaction. All operations must succeed before the transaction can be committed. If one or more operations fail, the entire transaction is rolled back.

4, Application in. Net Core

  1. Add controller - DaprStateController in the project [DaprFrontEnd]   Various operations used to display status

[Route("[controller]")]
[ApiController]
public class StateController : ControllerBase
{
    private readonly ILogger<DaprStateController> _logger;
    private readonly DaprClient _daprClient;
    public StateController(ILogger<StateController> logger, DaprClient daprClient)
    {
        _logger = logger;
        _daprClient = daprClient;
    }
    /// <summary>
    /// Get value
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    public async Task<ActionResult> GetAsync()
    {
        var result = await _daprClient.GetStateAsync<string>("statestore", "guid");
        return Ok(result);
    }
    /// <summary>
    /// Save value
    /// </summary>
    /// <returns></returns>
    [HttpPost]
    public async Task<ActionResult> PostAsync()
    {
        await _daprClient.SaveStateAsync<string>("statestore", "guid", Guid.NewGuid().ToString(), new StateOptions() { Consistency = ConsistencyMode.Strong });
        return Ok("done");
    }
    /// <summary>
    /// Delete value
    /// </summary>
    /// <returns></returns>
    [HttpDelete]
    public async Task<ActionResult> DeleteAsync()
    {
        await _daprClient.DeleteStateAsync("statestore", "guid");
        return Ok("done");
    }
    /// <summary>
    /// adopt tag Prevent concurrency conflicts and save values
    /// </summary>
    /// <returns></returns>
    [HttpPost("withtag")]
    public async Task<ActionResult> PostWithTagAsync()
    {
        var (value, etag) = await _daprClient.GetStateAndETagAsync<string>("statestore", "guid");
        await _daprClient.TrySaveStateAsync<string>("statestore", "guid", Guid.NewGuid().ToString(), etag);
        return Ok("done");
    }
    /// <summary>
    /// adopt tag Prevent concurrency conflicts and delete values
    /// </summary>
    /// <returns></returns>
    [HttpDelete("withtag")]
    public async Task<ActionResult> DeleteWithTagAsync()
    {
        var (value, etag) = await _daprClient.GetStateAndETagAsync<string>("statestore", "guid");
        return Ok(await _daprClient.TryDeleteStateAsync("statestore", "guid", etag));
    }
    /// <summary>
    /// Get value from binding, key value name Get from routing template
    /// </summary>
    /// <param name="state"></param>
    /// <returns></returns>
    [HttpGet("frombinding/{name}")]
    public async Task<ActionResult> GetFromBindingAsync([FromState("statestore", "name")] StateEntry<string> state)
    {
        return await Task.FromResult<ActionResult>(Ok(state.Value));
    }
    /// <summary>
    /// Get and modify the value according to the binding, including the key value name Get from routing template
    /// </summary>
    /// <param name="state"></param>
    /// <returns></returns>
    [HttpPost("withbinding/{name}")]
    public async Task<ActionResult> PostWithBindingAsync([FromState("statestore", "name")] StateEntry<string> state)
    {
        state.Value = Guid.NewGuid().ToString();
        return Ok(await state.TrySaveAsync());
    }
    /// <summary>
    /// Get multiple values
    /// </summary>
    /// <returns></returns>
    [HttpGet("list")]
    public async Task<ActionResult> GetListAsync()
    {
        var result = await _daprClient.GetBulkStateAsync("statestore", new List<string> { "guid" }, 10);
        return Ok(result);
    }
    /// <summary>
    /// Delete multiple values
    /// </summary>
    /// <returns></returns>
    [HttpDelete("list")]
    public async Task<ActionResult> DeleteListAsync()
    {
        var data = await _daprClient.GetBulkStateAsync("statestore", new List<string> { "guid" }, 10);
        var removeList = new List<BulkDeleteStateItem>();
        foreach (var item in data)
        {
            removeList.Add(new BulkDeleteStateItem(item.Key, item.ETag));
        }
        await _daprClient.DeleteBulkStateAsync("statestore", removeList);
        return Ok("done");
    }
}

2. Startup procedure

dapr run --dapr-http-port 3501 --app-port 8230  --app-id frontend dotnet  .\DaprFrontEnd.dll

3. Calling process:

  

  

5, Summary:

  The Dapr state management building block provides an API for storing key / value data in various data stores. The API supports the following:

  • Batch operation
  • Strong consistency and final consistency
  • Optimistic concurrency control
  • Multiple transactions

Posted by GreyBoy on Sun, 31 Oct 2021 05:40:43 -0700