Detailed. NET client implements the pipeline pipeline and things transactions in Redis

Source: Internet
Author: User
Tags redis server
This paper mainly introduces the. NET client implements the knowledge of pipelines (PipeLine) and Things (transactions) in Redis. Have a good reference value, follow the small series together to see it

Preface

Pipeline (PipeLine) features in Redis: A brief description of how Redis sends multiple commands at once from the client, and how the server-to-client responds to multiple commands at once.

Redis uses the client-server model and the TCP server for the request/response protocol, which means that a request has the following steps to complete: 1, the client sends a query command to the server, and then typically waits for the server to be blocked in an appropriate manner. 2. The server processes the query command and sends it back to the client accordingly. This will be connected through the network, if it is a local loopback interface can be particularly rapid response, but if you go outside the network, or even outside the network to do a series of layer forwarding, it is extra egg pain. Regardless of the network latency, the overall response time will be consumed. So if you send 1 commands at a time, the network delay is 100ms, we have to do. Then if 1 times Send 1000 commands, then the network delay 100*1000ms is very difficult to tolerate.

For the above problem, Redis provides pipeline (Pipeline) functionality after the 2.6 release. He can enable the client to process a new request without reading the old response. This allows you to send multiple commands to the server without waiting for a reply until the last step reads the reply. This is known as a pipeline (PipeLine) and is a technology that has been widely used for decades. For example, many POP3 protocol implementations already support this feature, greatly speeding up the process of downloading new e-mail from the server.

Then the business of the word, often encountered, not much Haw, the goal to be consistent is good, is a group of operations how to make atomic operation, so that he can not go to the end, back to the original point.

Brief introduction of Wireshark grasping bag tool

In order to let everyone have a more image of the pipeline, this section we first talk about Wireshark grab the package tool, he will let you see the client to the server through the TCP protocol sent by the process of REDIS commands and details.

Wireshark is able to catch every message that the system sends and receives, and we only do a few brief descriptions of the filters here. That's what he looks like, and when you open it you can grope for his usage.

Briefly describe several filter rules:

1, IP filtering: target IP Filtering: ip.dst==172.18.8.11, source IP address filtering: ip.src==192.168.1.12;

2, Port filtering: tcp.port==80, this rule is the source port and the destination port of 80 are filtered out. Using tcp.dstport==80 only to filter the destination port to 80, tcp.srcport==80 only filter packets with source port 80;

3, protocol filtering: Directly in the Fiter box to enter the name of the protocol, such as: HTTP,TCP,UDP, ...

4, HTTP Mode filter: Filter get packet, http.request.method== "Get", filter post packet, http.request.method== "POST";

5, if you use multi-conditional filtering, you need to add the connection symbol, and. such as ip.src==192.168.1.12 and http.request.method== "POST" and tcp.srcport==80

Stackexchange.redis Implementing a Redis pipeline (Pipeline)

Two pictures The pipeline will be clear at a glance.

If the client makes multiple requests to the Redis server, the general normal mode is

If the client requests the Redis server multiple times, the pipeline mode is the same

General mode we on the code:


public static void Getnopipelining ()  {for   (var i = 0; i < 3; i++)   {    var key = "Name:" + i;    Db. Stringappend (Key, "Zhang Long Hao");   }  


View data for TCP request messages

In this way, you can see that the key of the 3 TCP requests that I have circled is name:0,name:1,name:2 this way.

So we use pipeline mode

public static void Getpipelining ()  {   var batch = db. Createbatch ();   for (int i = 0; i < 3; i++)   {    var key = "Mename:" + i;    Batch. Stringappendasync (Key, "Zhang Long Hao");   }   Batch. Execute ();  }


Look at the request again.

This clearly shows that 1 requests have been sent out of multiple commands. Then we can achieve this effect without createbatch ().

var a = db. Stringappendasync ("Zlh:1", "Zhanglonghao1");   var b = db. Stringappendasync ("Zlh:2", "Zhanglonghao2");   var c = db. Stringappendasync ("Zlh:3", "Zhanglonghao3");   var AA = db. Wait (a);   var BB = db. Wait (a);   var cc = db. Wait (a);


In the next step we do a simple performance comparison. The code is as follows:

static void Main (string[] args)  {   Stopwatch watch = new Stopwatch ();   Stopwatch watch1 = new Stopwatch ();   Watch. Start ();   Getnopipelining ();   Console.WriteLine ("General cycle time:" + watch.) Elapsedmilliseconds);   Watch. Stop ();   Watch1. Start ();   Getpipelining ();   Console.WriteLine ("Pipelining Insertion Time:" + watch1. Elapsedmilliseconds);   Watch1. Stop ();   Console.ReadLine ();  }  public static void Getnopipelining ()  {for   (var i = 0; i < i++)   {    var key = "Name:" + i;
  
   db. Stringappend (Key, "Zhang Long Hao");   }  public static void Getpipelining ()  {   var batch = db. Createbatch ();   for (int i = 0; i < i++)   {    var key = "Mename:" + i;    Batch. Stringappendasync (Key, "Zhang Long Hao");   }   Batch. Execute ();  }
  


The results are as follows:

Here I would also like to say the Stackexchange.redis of the three command mode, where the use of 2 and 3 mode to send commands, will be encapsulated in the pipeline by default, if not, you can do a small demo test:

1, Sync: Synchronous mode, will block the caller directly, but will not block other threads.

2. Async: Asynchronous mode, encapsulated using the task model.

3, Fire-and-forget: Send the command, and then completely do not care when the final time to complete the command operation. In Fire-and-forget mode, all commands immediately get the return value, which is the default value of the return value type, such as if the operation return type is bool will immediately get false, because false = Default (BOOL).

Stackexchange.redis Implementing Redis transactions (transactions)

Look at the official documents, I can only say that the implementation of the very strange it. I first described my environment, is to prepare an empty Redis library, and then step by step down, we write code to see the results, to engage in this business.

static void Main (string[] args)  {   var tran = db. CreateTransaction ();   Tran. Addcondition (Condition.listindexnotequal ("Zlh:1", 0, "Zhanglonghao"));     Tran. Listrightpushasync ("Zlh:1", "Zhanglonghao");    BOOL committed = Tran. Execute ();   Console.WriteLine (committed);   Console.ReadLine ();  }


The result of execution is: true. The results in the database are as follows, indicating that we inserted successfully.

That is: If key is: Zlh:1 's list collection at the beginning of index 0 Value!=zhanglonghao, we insert a data from the right side of the list key for Zlh:1value for Zhanglonghao, success. Because the first action is an empty library. 0 is not really Zhang Long Hao.

Data is not emptied, continue on the code.

static void Main (string[] args)  {   var tran = db. CreateTransaction ();   Tran. Addcondition (Condition.listindexnotequal ("Zlh:1", 0, "Zhanglonghao"));     Tran. Listrightpushasync ("Zlh:1", "Zhanglonghao1");      BOOL committed = Tran. Execute ();   Console.WriteLine (committed);   Console.ReadLine ();  }


The result is false, the database does not increment or decrement data. have been consistent with data for a long time.

Cause Analysis: 0 at this time for Zhanglonghao, so Listindexnotequal ("Zlh:1", 0, "Zhanglonghao") for the false proposition, directly rollback, do not execute the following insert command.

Data is not emptied, continue on the code:

static void Main (string[] args)  {   var tran = db. CreateTransaction ();   Tran. Addcondition (Condition.listindexequal ("Zlh:1", 0, "Zhanglonghao"));     Tran. Listrightpushasync ("Zlh:1", "Zhanglonghao1");      BOOL committed = Tran. Execute ();   Console.WriteLine (committed);   Console.ReadLine ();  }


The result is true, and the data results are as follows, increasing a value of ZHANGLONGHAO1:

Cause Analysis: listindexequal ("Zlh:1", 0, "Zhanglonghao") is the true proposition, perform the following operation, commit the thing.

Data is not deleted continue on the code:

static void Main (string[] args)  {   var tran = db. CreateTransaction ();   Tran. Addcondition (Condition.listindexequal ("Zlh:1", 0, "Zhanglonghao"));     Tran. Listrightpushasync ("Zlh:1", "Zhanglonghao2");   Tran. Addcondition (Condition.listindexnotequal ("Zlh:1", 0, "Zhanglonghao"));   Tran. Listrightpushasync ("Zlh:1", "Zhanglonghao3");   BOOL committed = Tran. Execute ();   Console.WriteLine (committed);   Console.ReadLine ();  }


The result is false, the database data has long been consistent with the above, no increase.

Analysis Reason: Condition.listindexequal ("Zlh:1", 0, "Zhanglonghao") is true, but to the listindexnotequal below ("Zlh:1", 0, "Zhanglonghao") to False. Therefore the whole thing's operation rollback, does not execute, therefore the database has not changed.

In this case, I will not write redundant code, but I would like to say a few points to note:

1, the operation of the command must be asynchronous operation.

2, the command executed in the thing will not see the result directly, so the result cannot be used to judge the following code, because the current asynchronous command will not have any effect on the database before execute ().

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.