C#客户端Redis服务器的分布式缓存

网友投稿 1078 2023-04-28

C#客户端Redis服务器的分布式缓存

C#客户端Redis服务器的分布式缓存

介绍

在这篇文章中,我想介绍我知道的一种最紧凑的安装和配置Redis服务器的方式。另外,我想简短地概述一下在.NET / C#客户端下Redis hash(哈希类型)和list(链表)的使用。

在这篇文章主要讲到:

安装Redis服务器(附完整的应用程序文件设置)Redis服务器保护(配置身份验证)配置服务器复制从C#应用程序访问缓存使用Redis ASP.NET会话状态Redis 集合(Set)、列表(List)和事务处理用法示例说明附加的源(Redis Funq LoC MVC项目:举例)缓存的优化思路

背景

Redis是最快也是功能最丰富的内存Key-Value数据存储系统之一。

缺点

没有本地数据缓存(如在Azure缓存同步本地数据缓存)没有完全集群化的支持(不过,可能今年年底会实现)

优点

易于配置使用简单高性能支持不同的数据类型(如hash(哈希类型)、list(链表)、set(集合)、sorted set(有序集))ASP.NET会话集成Web UI用于浏览缓存内容

下面我将简单说明如何在服务器上安装和配置Redis,并用C#使用它。

Redis的安装

Redis应用程序的完整文件也可以从压缩文件(x64)得到。

当你拥有了全套的应用程序文件(如下图所示),

导航到应用程序目录,然后运行以下命令:

sc create %name% binpath= "\"%binpath%\" %configpath%" start= "auto" DisplayName= "Redis"

其中:

%name%——服务实例的名称,例如:redis-instance;%binpath%——到项目exe文件的路径,例如:C:\Program Files\Redis\RedisService_1.1.exe;%configpath%——到Redis配置文件的路径,例如:C:\Program Files\Redis\redis.conf;

举例:

sc create Redis start= auto DisplayName= Redis binpath= "\"C:\Program Files\Redis\RedisService_1.1.exe\" \"C:\Program Files\Redis\redis.conf\""

即应该是这样的:

请确保有足够的权限启动该服务。安装完毕后,请检查该服务是否创建成功,当前是否正在运行:

Redis服务器保护:密码,IP过滤

保护Redis服务器的主要方式是使用Windows防火墙或活跃的网络连接属性设置IP过滤。此外,还可以使用Redis密码设置额外保护。这需要用下面的方式更新Redis配置文件(redis.conf):

首先,找到这行:

# requirepass foobared

删除开头的#符号,用新密码替换foobared:

requirepass foobared

然后,重新启动Redis Windows服务!

当具体使用客户端的时候,使用带密码的构造函数:

RedisClient client = new RedisClient(serverHost, port, redisPassword);

Redis服务器复制(主—从配置)

Redis支持主从同步,即,每次主服务器修改,从服务器得到通知,并自动同步。大多复制用于读取(但不能写)扩展和数据冗余和服务器故障转移。设 置两个Redis实例(在相同或不同服务器上的两个服务),然后配置其中之一作为从站。为了让Redis服务器实例是另一台服务器的从属,可以这样更改配 置文件:

找到以下代码:

# slaveof

替换为:

slaveof 192.168.1.1 6379

(可以自定义指定主服务器的真实IP和端口)。如果主服务器配置为需要密码(验证),可以如下所示改变redis.conf,找到这一行代码:

# masterauth

删除开头的#符号,用主服务器的密码替换,即:

masterauth mastpassword

现在这个Redis实例可以被用来作为主服务器的只读同步副本。

用C#代码使用Redis缓存

用C#代码使用Redis运行Manage NuGet包插件,找到ServiceStack.Redis包,并进行安装。

直接从实例化客户端使用Set/Get方法示例:

string host = "localhost"; string elementKey = "testKeyRedis";  using (RedisClient redisClient = new RedisClient(host)) {       if (redisClient.Get(elementKey) == null)       {            // adding delay to see the difference            Thread.Sleep(5000);            // save value in cache            redisClient.Set(elementKey, "some cached value");       }       // get value from the cache by key       message = "Item value is: " + redisClient.Get("some cached value"); }

类型化实体集更有意思和更实用,这是因为它们操作的是确切类型的对象。在下面的代码示例中,有两个类分别定义为Phone和Person——phone的主人。每个phone实例引用它的主人。下面的代码演示我们如何通过标准添加、删除和发现缓存项:

public class Phone {    public int Id { get; set; }    public string Model { get; set; }    public string Manufacturer { get; set; }    public Person Owner { get; set; } }  public class Person {     public int Id { get; set; }     public string Name { get; set; }     public string Surname { get; set; }     public int Age { get; set; }     public string Profession { get; set; } }  using (RedisClient redisClient = new RedisClient(host)) {      IRedisTypedClient phones = redisClient.As();      Phone phoneFive = phones.GetValue("5");      if (phoneFive == null)      {           // make a small delay           Thread.Sleep(5000);           // creating a new Phone entry           phoneFive = new Phone           {                Id = 5,                Manufacturer = "Motorolla",                Model = "xxxxx",                Owner = new Person                {                     Id = 1,                     Age = 90,                     Name = "OldOne",                     Profession = "sportsmen",                     Surname = "OldManSurname"                }           };           // adding Entry to the typed entity set           phones.SetEntry(phoneFive.Id.ToString(), phoneFive);      }      message = "Phone model is " + phoneFive.Manufacturer;      message += "Phone Owner Name is: " + phoneFive.Owner.Name; }

在上面的例子中,我们实例化了输入端IRedisTypedClient,它与缓存对象的特定类型——Phone类型一起工作。

Redis ASP.NET会话状态

                  

注意,此密码是可以选择的,看服务器是否需要认证。它必须被真实的值替换或删除,如果Redis服务器不需要身份验证,那么服务器属性和端口得由具体的数值代替(默认端口为6379)。然后在项目中,你才可以使用会话状态:

// in the Global.asax public class MvcApplication1 : System.Web.HttpApplication {     protected void Application_Start()     {         //....     }      protected void Session_Start()     {         Session["testRedisSession"] = "Message from the redis ression";     } }  在Home controller(主控制器):  public class HomeController : Controller {     public ActionResult Index()     {        //...        ViewBag.Message = Session["testRedisSession"];        return View();     } //... }

结果:

ASP.NET输出缓存提供者,并且Redis可以用类似的方式进行配置。

Redis Set(集合)和List(列表)

主要要注意的是,Redis列表实现IList,而Redis集合实现ICollection。下面来说说如何使用它们。

当需要区分相同类型的不同分类对象时,使用列表。例如,我们有“mostSelling(热销手机)”和“oldCollection(回收手机)”两个列表:

string host = "localhost"; using (var redisClient = new RedisClient(host)) {     //Create a 'strongly-typed' API that makes all Redis Value operations to apply against Phones     IRedisTypedClient redis = redisClient.As();      IRedisList mostSelling = redis.Lists["urn:phones:mostselling"];     IRedisList oldCollection = redis.Lists["urn:phones:oldcollection"];      Person phonesOwner = new Person         {             Id = 7,             Age = 90,             Name = "OldOne",             Profession = "sportsmen",             Surname = "OldManSurname"         };      // adding new items to the list     mostSelling.Add(new Phone             {                 Id = 5,                 Manufacturer = "Sony",                 Model = "768564564566",                 Owner = phonesOwner             });      oldCollection.Add(new Phone             {                 Id = 8,                 Manufacturer = "Motorolla",                 Model = "324557546754",                 Owner = phonesOwner             });      var upgradedPhone  = new Phone     {         Id = 3,         Manufacturer = "LG",         Model = "634563456",         Owner = phonesOwner     };      mostSelling.Add(upgradedPhone);      // remove item from the list     oldCollection.Remove(upgradedPhone);      // find objects in the cache     IEnumerable LGPhones = mostSelling.Where(ph => ph.Manufacturer == "LG");      // find specific     Phone singleElement = mostSelling.FirstOrDefault(ph => ph.Id == 8);      //reset sequence and delete all lists     redis.SetSequence(0);     redisClient.Remove("urn:phones:mostselling");     redisClient.Remove("urn:phones:oldcollection"); }

当需要存储相关的数据集和收集统计信息,例如answer -> queustion给答案或问题投票时,Redis集合就非常好使。假设我们有很多的问题(queustion)和答案(answer ),需要将它们存储在缓存中。使用Redis,我们可以这么做:

附加资源说明

项目中引用的一些包在packages.config文件中配置。

Funq IoC的相关配置,以及注册类型和当前控制器目录,在Global.asax文件中配置。

你可以将tag字段设置成test3,test1,test2等。

Redis缓存配置——在web config文件(节点)以及RedisSessionStateProvider.cs文件中。

在MVC项目中有很多待办事项,因此,如果你想改进/继续,请更新,并上传。

如果有人能提供使用Redis(以及Funq IOC)缓存的MVC应用程序示例,本人将不胜感激。Funq IOC已经配置,使用示例已经在Question controller中。

注:部分取样于“ServiceStack.Examples-master”解决方案。

结论。优化应用程序缓存以及快速本地缓存

由于Redis并不在本地存储(也不在本地复制)数据,那么通过在本地缓存区存储一些轻量级或用户依赖的对象(跳过序列化字符串和客户端—服务端数据转换)来优化性能是有意义的。例如,在Web应用中,对于轻量级的对象使用’System.Runtime.Caching.ObjectCache‘ 会更好——用户依赖,并且应用程序时常要用。否则,当经常性地需要使用该对象时,就必须在分布式Redis缓存中存储大量容积的内容。用户依赖的对象举例——个人资料信息,个性化信息 。常用对象——本地化数据,不同用户之间的共享信息,等等。

下载源代码(Redis Funq LoC MVC 4版本)

链接

如何运行Redis服务:

文档:

.NET / C#示例:

关于如何用C#在Windows上使用Redis的好建议:

关于Redis:

Azure缓存

许可证

这篇文章,以及任何相关的源代码和文件,依据The Code Project Open License (CPOL)。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:将一列中多行相同的值只显示在一行
下一篇:十个正确使用 Redis 的技巧
相关文章