当前位置:网站首页>. Net core about redis pipeline and transactions

. Net core about redis pipeline and transactions

2022-07-07 13:38:00 Xiaodou whole sugar (Cx)

Redis Based on Request/Response agreement ( Stop waiting mechanism ) Of , Under normal circumstances , Client sends a command , wait for Redis Return results ,Redis Received an order , Response after processing . under these circumstances , If you need to execute a large number of commands at the same time , That is, wait for the last command to answer before executing , There's more than that RTT(Round Time Trip), And call the system frequently IO, Send network request . To improve efficiency , Now pipeline There is , It allows clients to send multiple commands at a time , Instead of waiting for the result of the last command , It's about the Internet Nagel The algorithm is a bit like (TCP_NODELAY Options ).pipeline Not only is it reduced RTT, It also reduces IO Call the number (IO Call involves switching between user state and kernel state ).

To support Pipeline, In fact, we need the support of the server , Client support is also required . For the server , What is needed is the ability to handle a client through the same TCP Multiple commands from connection , It can be understood as , Here, you can split multiple commands , As with a single command ( The old sticky phenomenon ),Redis That's how it works . And the client , To cache multiple commands , When the buffer is full or the sending conditions are met, it will be sent out , Last thing Redis Response to .

A simple description is actually sending multiple at one time redis Command channel server , Reduced number of requests

 Insert picture description here
Redis Of Pipeline and Transaction(Redis Business ) Different ,Transaction Will store the client's commands , Last one time execution , and Pipeline It's dealing with one ( batch ), Respond to one , In terms of the different processing mechanisms of the two ,Redis The execution of commands in a transaction is atomic ( Be careful , Some of the commands have errors and the subsequent commands will continue to execute , The atoms here say that command execution is complete , There will be no other Redis Interrupted by an order ), and pipeline The execution of the command in is not necessarily atomic . But there's a little difference , Namely pipeline In mechanism , The client does not call read Read out socket Buffer data inside ( Unless it's finished pipeline All orders in ), This has resulted in , If Redis The reply data fills the receive buffer (SO_RECVBUF), Then the client will pass ACK,WIN=0( Receiving window ) To control that the server can no longer send data , That way , The data will be buffered in Redis In the client response buffer . So we need to pay attention to control Pipeline Size

Batch The batch operation
StackExchange.Redis For continuous multiple requests such as caching , We will call related functions many times to execute Redis command . However, the disadvantage of this method is that every request needs to wait for the return result

If the network is in bad condition , It may cause a bad user experience .

For this kind of problem, you can use StackExchange.Redis Provided CreateBatch() solve

public void TestPipeLine()
        {
    
            IDatabase db = StackExchangeRedisHelper.GetDatabase();
            var batch = db.CreateBatch();
            Task t1 = batch.StringSetAsync("name", "bob");
            Task t2 = batch.StringSetAsync("age", 100);
            batch.Execute();
            Task.WaitAll(t1, t2);
            Console.WriteLine("Age:" + db.StringGet("age"));
            Console.WriteLine("Name:" + db.StringGet("name"));
        }

redis There are ACID Four features

redis The transaction of is actually running multi command , Then run the command you want to run , Finally, execute exec The command can be submitted once

StackExchange.Redis Control of things in

multi Commands just ensure that all commands in a thing can be executed together , Obviously, just realizing this is unsatisfying for most businesses .

therefore Redis Provides Watch Command to monitor a key To achieve the effect of optimistic lock .
stay StackExchange.Redis It's useless watch multi Order to execute , Because in a concurrent environment , There will be more than one watch multi command , It's all mixed up .

however StackExchange.Redis It provides a very simple and understandable way to create things , Here is the sample code

public void TestTran()
        {
    
            IDatabase db = StackExchangeRedisHelper.GetDatabase();
            string name = db.StringGet("name");
            string age = db.StringGet("age");
            Console.WriteLine("NAME:" + name);
            Console.WriteLine("Age:" + age);
            var tran = db.CreateTransaction();
            tran.AddCondition(Condition.StringEqual("name", name));
            Console.WriteLine("tran begin");
            tran.StringSetAsync("name", "leap");
            tran.StringSetAsync("age", 12);
            Thread.Sleep(4000);
            bool result = tran.Execute();
            Console.WriteLine(" Execution results :" + result);
            Console.WriteLine("Age:" + db.StringGet("age"));
            Console.WriteLine("Name:" + db.StringGet("name"));
        }

.net core The use of

using CoreRedis.Config;
using Microsoft.Extensions.Options;
using StackExchange.Redis;

namespace CoreRedis.RedisDataType
{
    
    
    public class RedisPipelineTranc
    {
    
        private ConnectionMultiplexer connectionMultiplexer;

        private readonly RedisConfig _redisConfig;

        private IDatabase db;

        public RedisPipelineTranc(IOptionsMonitor<RedisConfig> optionsMonitor)
        {
    
            _redisConfig = optionsMonitor.CurrentValue;
            connectionMultiplexer = ConnectionMultiplexer.Connect(_redisConfig.Value);
            db = connectionMultiplexer.GetDatabase();

        }

        public async Task<string>  testPipelien()
        {
    
            // intialize key with empty string
            await db.StringSetAsync("key", "");

            // create transaction that utilize multiplexing and pipelining
            ITransaction transacton = db.CreateTransaction();
            Task<long> appendA = transacton.StringAppendAsync("key", "a");
            Task<long> appendB = transacton.StringAppendAsync("key", "b");
            Task<long> appendc = transacton.StringAppendAsync("key", "c");

            if (await transacton.ExecuteAsync()) // sends "MULTI APPEND KEY a APPEND KEY b EXEC
                                                 // in single request to redis server
            {
    
                 order here doesn't matter, result is always - "abc". 
                 'a' and 'b' append always together in isolation of other Redis commands
                 'c' appends to "ab" because transaction is already executed successfully
                //await appendA;
                //await db.StringAppendAsync("key", "c");
                //await appendB;

                Task.WaitAll(appendA, appendB, appendc);
            }

            string value = db.StringGet("key"); // value is "abc"

            return value;
        }
    }
}

原网站

版权声明
本文为[Xiaodou whole sugar (Cx)]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/188/202207071136193994.html