本文将使用一个gitHub开源的组件技术来读写redis数据,使用的是基于以太网的TCP/IP实现,不需要额外的组件,读取操作只要放到后台线程就不会卡死线程,本组件支持超级方便的高性能读写操作

github地址:https://github.com/dathlin/HslCommunication                             如果喜欢可以star或是fork,还可以打赏支持。

官网地址:http://www.hslcommunication.cn/

联系作者及加群方式(激活码在群里发放):http://www.hslcommunication.cn/Cooperation

Redis是什么?


这个是一个实时的数据库技术,主要采用键值操作来存储数据的。官网是 https://redis.io/ ,官方的解释为(摘自百度百科):

redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。 [1] 
Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。
redis的官网地址,非常好记,是redis.io。(特意查了一下,域名后缀io属于国家域名,是british Indian Ocean territory,即英属印度洋领地)
目前,Vmware在资助着redis项目的开发和维护。

安装redis服务器


我们在使用前需要安装服务器,一般的windows的服务器来自于微软的项目:

https://github.com/MicrosoftArchive/redis/releases

虽然微软的项目只更新到了 redis3.2 版本。但是已经足够我们日常的使用了。

安装完成后,会自动的启动服务器。我们可以打开cmd来测试

服务器搭好后就可以使用C#来操作了。

再次随便聊聊,C#有个还可以的redis类库叫StackExchange.Redis

https://github.com/StackExchange/StackExchange.Redis

但是这个类库呢,总有些莫名其妙的问题,尤其是超时问题,始终没有得到很好的解决,所以我集成实现了redis的基本操作,给大家一个更多的选择。支持.net framework和.net standard

当你的程序实现了redis之后,程序架构变成了:

此处的redis相当于高速的数据缓存,可以部署在服务器的电脑上,可以部署在云端等等,任意其他的电脑上面。

接下来演示使用HSL来进行操作

从NUGET安装


Install-Package HslCommunication

  

关于两种模式


在PLC端,包括三菱,西门子,欧姆龙,AB以及Modbus Tcp客户端的访问器上,都支持两种模式,短连接模式和长连接模式,现在就来解释下什么原理。

短连接:每次读写都是一个单独的请求,请求完毕也就关闭了,如果服务器的端口仅仅支持单连接,那么关闭后这个端口可以被其他连接复用,但是在频繁的网络请求下,容易发生异常,会有其他的请求不成功,尤其是多线程的情况下。

长连接:创建一个公用的连接通道,所有的读写请求都利用这个通道来完成,这样的话,读写性能更快速,即时多线程调用也不会影响,内部有同步机制。如果服务器的端口仅仅支持单连接,那么这个端口就被占用了,比如三菱的端口机制,西门子的Modbus tcp端口机制也是这样的。以下代码默认使用长连接,性能更高,还支持多线程同步。

在短连接的模式下,每次请求都是单独的访问,所以没有重连的困扰,在长连接的模式下,如果本次请求失败了,在下次请求的时候,会自动重新连接服务器,直到请求成功为止。另外,尽量所有的读写都对结果的成功进行判断。

DEMO示例:


下面的一个项目是这个组件的访问测试项目,您可以进行初步的访问的测试,免去了您写测试程序的麻烦,三菱的界面和西门子的界面几乎是一致的。可以同时参考。该项目位于本篇文章开始处的Gitbub源代码里面的

下载地址为:HslCommunicationDemo.zip

可以用来浏览你的redis到底有什么数据,以及这个数据是什么,初步支持了  string,list,hash 数据类型。

当你写入的key名字带有:(英文状态)时。这个浏览器还会对数据进行分类整理、

关于redis指令


http://doc.redisfans.com/index.html

原生的指令有很多,这个库里也是支持了大部分的操作,如果你需要的功能还没有支持,比如 获取一个键的数据信息, 将指令参数按照空格输入进去就行

        private void button16_Click( object sender, EventArgs e )
{
OperateResult<string> read = redisClient.ReadCustomer("GET A" );
if (read.IsSuccess)
{
// read.Content 就是从服务器返回的数据 例如为 $2\r\n11\r\n 需要自己提炼真实的数据
MessageBox.Show( read.Content );
}
else
{
MessageBox.Show( read.Message );
}
}

  

下面列举一些示例

简单使用


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using HslCommunication.Enthernet.Redis;
using HslCommunication; namespace WindowsFormsApp3
{
public partial class Form1 : Form
{
public Form1( )
{
InitializeComponent( );
} private RedisClient redisClient = new RedisClient( "127.0.0.1", 6379, "" );
private void button1_Click( object sender, EventArgs e )
{
OperateResult<string> read = redisClient.ReadKey( "a" );
if (read.IsSuccess)
{
MessageBox.Show( read.Content );
}
else
{
MessageBox.Show( read.Message );
}
}
}
}

  

结果如下:

显示的值就是我们之前写入的操作,主要,redis区分大小写,你读  A  和读 a 是不一样的。

上述的代码已经进行了严格的验证,上面情况会读取失败呢?网络异常或是 a 不存在

我们来看看写入键值:

        private void button2_Click( object sender, EventArgs e )
{
OperateResult write = redisClient.WriteKey( "a", "abcde" );
}

上述就没有对写入成功与否进行验证,只要是网络正常基本都是成功的。

写完后我们再读取一次:

如果想写入一个有生命周期的key,比如100s后自动消失的key

        private void button3_Click( object sender, EventArgs e )
{
OperateResult write = redisClient.WriteExpireKey( "b", "abcde", 100 );
}

这样就写入了一个带生命周期的key了。

批量读写


如果想要一次性写入或是读取很多键值:

        private void button4_Click( object sender, EventArgs e )
{
OperateResult<string[]> read = redisClient.ReadKey( new string[] { "a", "b" } );
if (read.IsSuccess)
{
string[] result = read.Content;
}
else
{
MessageBox.Show( read.Message );
}
}

写入的操作如下:

        private void button5_Click( object sender, EventArgs e )
{
redisClient.WriteKey( new string[] { "a", "b" }, new string[] { "abcde", "ihsdasd" } );
}

此处省略了对写入结果的验证,为了安全起见,你应该添加。

获取旧值,并设置一个新的值进去

        private void button6_Click( object sender, EventArgs e )
{
OperateResult<string> read = redisClient.ReadAndWriteKey( "a", "aaaaaa" );
if (read.IsSuccess)
{
MessageBox.Show( read.Content );
}
else
{
MessageBox.Show( read.Message );
}
}

  

递增递减操作。


这个基本功能也是很常见的、

我们先写 BB 为 0

然后我们再给这个值加1,并返回1的操作。

        private void button7_Click( object sender, EventArgs e )
{
OperateResult<int> read = redisClient.IncrementKey( "BB" );
if (read.IsSuccess)
{
MessageBox.Show( "Value:" + read.Content );
}
else
{
MessageBox.Show( read.Message );
}
}

同理也支持减一操作,增加指定的数据操作,减去指定的数据操作。

列表操作


redis也支持存储数组数据信息

我们创建一个数组,并往里面塞东西,当然支持从数组的左侧塞,也支持从右侧塞,下面就是左侧的例子

        private void button8_Click( object sender, EventArgs e )
{
redisClient.ListLeftPush( "C", "123" );
}

这样就创建了一个数组,数组数据的读取,并不是get了,而是变成了 LRANGE 0 -1 代表读取整个的数组

用代码来读取就是

        private void button9_Click( object sender, EventArgs e )
{
OperateResult<string[]> read = redisClient.ListRange( "C", 0, -1 );
if (read.IsSuccess)
{
// 列表变成了一个数组信息
string[] result = read.Content;
}
else
{
MessageBox.Show( read.Message );
}
}

当然,当你的数组很大时。比如1000个长度时,你可以读取中间任意个数组。

获取数组长度


当你不知道一个数组的长度,不想在读取所有的数组信息的情况下,读取到长度

        private void button10_Click( object sender, EventArgs e )
{
int length = redisClient.GetListLength( "C" ).Content; // 此处就是1
}

获取指定索引的数据


        private void button11_Click( object sender, EventArgs e )
{
string read = redisClient.ReadListByIndex( "C", 0 ).Content;
}

注意,当C不是list时,会引发错误。  

修剪列表信息


当数组过长时,我们可以修剪数组来达到收缩的目的

        private void button12_Click( object sender, EventArgs e )
{
redisClient.ListTrim( "C", 0, 9 );// 10个长度,保留0-9索引的数据
}

  

返回并移除开始处的列表


        private void button13_Click( object sender, EventArgs e )
{
OperateResult<string> read = redisClient.ListLeftPop( "C" );
if (read.IsSuccess)
{
MessageBox.Show( read.Content );
}
else
{
MessageBox.Show( read.Message );
}
}

  移除并返回测试的也是可以的。

哈希值读写


哈希值的意思是一个键的值是由多个键值组成的

        private void button14_Click( object sender, EventArgs e )
{
redisClient.WriteHashKey( "D", "A", "1" );
redisClient.WriteHashKey( "D", "B", "2" );
redisClient.WriteHashKey( "D", "C", "3" );
}

  

相当于是键 D 的域 A 写入1, B写入2,C写入3

你一次可以读取所有的C的域集合,或是值集合,或是域+值集合,下面演示了一个示例,读取域+值集合

        private void button15_Click( object sender, EventArgs e )
{
OperateResult<string[]> read = redisClient.ReadHashKeyAll( "C" );
if (read.IsSuccess)
{
// 列表变成了一个域+值信息
// A
// 1
// B
// 2
// C
// 3
string[] result = read.Content;
}
else
{
MessageBox.Show( read.Message );
}
}

  

C# 读写redis C#读写实时数据库的更多相关文章

  1. redis sentinel 读写分离

    redis sentinel 读写分离 https://www.jianshu.com/p/d1636776bb40

  2. Java Redis的Pipeline管道,批量操作,节省大量网络往返时间 & Redis批量读写(hmset&hgetall) 使用Pipeline

    一般情况下,大家使用redis去put/get都是先拿到一个jedis实例,然后操作,然后释放连接:这种模式是 请求-响应,请求-响应 这种模式,下一次请求必须得等第一次请求响应回来之后才可以,因为r ...

  3. jedis使用管道(pipeline)对redis进行读写(使用hmset、hgetall测试)

    一般情况下,Redis Client端发出一个请求后,通常会阻塞并等待Redis服务端处理,Redis服务端处理完后请求命令后会将结果通过响应报文返回给Client.这有点类似于HBase的Scan, ...

  4. windows下Redis 主从读写分离部署

    原文:windows下Redis 主从读写分离部署 1.可直接下载window下的运行文件(下面这个链接) 也可以浏览github 查看相应的版本说明文档 https://github.com/Ser ...

  5. 使用ServiceStack.Redis实现Redis数据读写

    原文:使用ServiceStack.Redis实现Redis数据读写 User.cs实体类 public class User { public string Name { get; set; } p ...

  6. 在项目中部署redis的读写分离架构(包含节点间认证口令)

    #### 在项目中部署redis的读写分离架构(包含节点间认证口令) ##### 1.配置过程 ---  1.此前就是已经将redis在系统中已经安装好了,redis utils目录下,有个redis ...

  7. Flink读写Redis(三)-读取redis数据

    自定义flink的RedisSource,实现从redis中读取数据,这里借鉴了flink-connector-redis_2.11的实现逻辑,实现对redis读取的逻辑封装,flink-connec ...

  8. Redis的读写分离

    1.概述 随着企业业务的不断扩大,请求的并发量不断增长,Redis可能终会出现无法负载的情况,此时我们就需要想办法去提升Redis的负载能力. 读写分离(主从复制)是一个比较简单的扩展方案,使用多台机 ...

  9. flinksql读写redis

    0.前言 最近有个需求,需要使用flinksql读写redis,由于官网上并没有redis的connector,在网上找了很久,开源的几个connector又没法满足要求,所有这里就自己动手实现了一个 ...

随机推荐

  1. Django RF:学习笔记(8)——快速开始

    Django RF:学习笔记(8)——快速开始 安装配置 1.使用Pip安装Django REST Framework: pip install djangorestframework 2.在Sett ...

  2. 141. Linked List Cycle(判断链表是否有环)

    141. Linked List Cycle Given a linked list, determine if it has a cycle in it. Follow up:Can you sol ...

  3. springcloud19---springCloudConfig

    Spring-cloud-config : 统一管理配置的组件,不同的环境不同的管理(连接池.数据库配置不一样).不同时间需要动态调整配置(双十一最大连接数要大). 分布式配置也可以使用config或 ...

  4. Python笔记 #18# Pandas: Grouping

    10 Minutes to pandas 引 By “group by” we are referring to a process involving one or more of the foll ...

  5. 20145326蔡馨熠 实验三 "敏捷开发与XP实践"

    20145326蔡馨熠 实验三 "敏捷开发与XP实践" 程序设计过程 一.实验内容 使用 git 上传代码 使用 git 相互更改代码 实现代码的重载 1.git上传代码 首先我通 ...

  6. 反射调用发生错误信息 LoadNeither

    错误信息: Service cannot be started. System.Reflection.TargetInvocationException: Exception has been thr ...

  7. 【查看内存】Linux查看内存使用情况(一)

    用 'top -i' 看看有多少进程处于 Running 状态,可能系统存在内存或 I/O 瓶颈,用 free 看看系统内存使用情况,swap 是否被占用很多,用 iostat 看看 I/O 负载情况 ...

  8. Android -- service的开启方式, start开启和绑定开启服务,调用服务的的方法, aidl调用远程服务

    1. 概述 bindService() 绑定服务  可以得到服务的代理人对象,间接调用服务里面的方法. 绑定服务: 间接调用服务里面的方法.           如果调用者activity被销毁了, ...

  9. Binary Tree Zigzag Level Order Traversal,z字形遍历二叉树,得到每层访问的节点值。

    问题描述: Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from l ...

  10. Codeforces Round #402 (Div. 2) A,B,C,D,E

    A. Pupils Redistribution time limit per test 1 second memory limit per test 256 megabytes input stan ...