第三方缓存软件:Redis 和 Memcached

第三方缓存软件:memcached和redis
memcached和redis相同点:都是以键值对的形式来存储数据,通俗讲就是一个大的hashtable
缓存数据都是存在内存中 key-value

不同点:
Memcached:
1、一个key所对应的值必须要通过客户端序列化成二进制流存储 (即:byte[] ,即:将一个对象存储到Memcached缓存中,就需要将这个对象序列化成一个二进制流,而将来从要从内存中拿出来这个对象,又需要将这个二进制流反序列化成对象,所以它的缺点就是,由于序列化反序列化频繁,需要消耗CPU比较大)
2、一个key所对应的值最大只能是1M  (这个1M已经很大了,一般都是够用的了)
3、传统的memcached是不支持内存数据的持久化操作,因为它将数据存储在内存当中的,当服务器重启,数据会丢失
4、可以配置读写分离
5、多线程

Redis: 
1、一个key对应的值可以是 string,list<>,sortlist<>,Set,OrderdSet,实现队列,免去序列化操作(大大提升了CPU的工作效率)
2、redis可以按照设置策略将内存中的数据持久,即:将内存中的数据写入到服务器硬盘中,当服务器重启以后自动回从服务器硬盘中将数据重新加载回内存
3、可以配置redis的读写分离
4、单线程


如何通过c#来访问:
memcached和redis都是以服务进程的方式驻留服务器上,同时用socket监听请求,通过流来传输数据

他们都提供了c#客户端访问类库(一组.dll),那么我们只要学这个程序集怎么使用就行了。

Redis介绍:

Redis是一个开源,先进的key-value存储,并用于构建高性能,可扩展的Web应用程序的完美解决方案。


Redis从它的许多竞争继承来的三个主要特点:

Redis数据库完全在内存中,使用磁盘仅用于持久性。
相比许多键值数据存储,Redis拥有一套较为丰富的数据类型。
Redis可以将数据复制到任意数量的从服务器。

Redis 优势
异常快速:Redis的速度非常快,每秒能执行约11万集合,每秒约81000+条记录。
支持丰富的数据类型:Redis支持最大多数开发人员已经知道像列表,集合,有序集合,散列数据类型。这使得它非常容易解决各种各样的问题,因为我们知道哪些问题是可以处理通过它的数据类型更好。
操作都是原子性:所有Redis操作是原子的,这保证了如果两个客户端同时访问的Redis服务器将获得更新后的值。
多功能实用工具:Redis是一个多实用的工具,可以在多个用例如缓存,消息,队列使用(Redis原生支持发布/订阅),任何短暂的数据,应用程序,如Web应用程序会话,网页命中计数等。

Redis的使用

在ASP.NET Web API中使用Redis

缓存技术Redis在C#中的使用及Redis的封装

Redis操作的封装类   

Redis快速入门

首先需要去网上下载一个Redis软件:下载地址:https://github.com/MSOpenTech/redis/releases

下载下来后文件解压到E盘根目录下。 E:\Redis

如果直接执行redis-server.exe这个服务端是不能使用redis.windows.conf的这个配置文件的,

要想使用这个redis.windows.conf配置文件,就需要进入cmd打开cmd.exe命令

运行cmd -->C:\User\凡斌>E: (进入E盘)-->E:\>cd E:\Redis (进入E盘的Redis目录下) -->E:\Redis>redis-server redis.windows.conf (这里表示使用redis.windows.conf这个配置文件的开启方式,即:开启redis-server服务,但是这个服务器使用了redis.windows.conf这个配置文件)

以上就将Redis的服务开启了。

现在我们需要在代码中来使用这个服务器了。

代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RedisDemo
{
    using ServiceStack.Redis;
    class Program
    {
        static void Main(string[] args)
        {

            //使用Redis,就需要首先安装Redis,打开网址 http://www.nuget.org/ 在里面搜索“Redis” 
            //1,搜索到很多选项,然后我们选择:C# Redis client for the Redis NoSQL DB 这一项,然后打开链接
            //2,在vs中选择 工具->库程序包管理器(N)->程序包管理器控制台(O)->输入:PM>  Install-Package ServiceStack.Redis
            //安装完毕后我们发现项目中的packages文件夹中多了:ServiceStack.Common.dll,ServiceStack.Interfaces.dll,ServiceStack.Redis.dll,ServiceStack.Text.dll四个dll文件
            //其实我们也可以去网上直接下载这个4个dll文件,引用到项目中也是可以的。

            //正式使用了。正式使用之前需要手动开启Redis服务器:我的Redis放在E盘的根目录下。
            //运行cmd -->C:\User\凡斌>E: (进入E盘)-->E:\>cd E:\Redis (进入E盘的Redis目录下) -->E:\Redis>redis-server redis.windows.conf (这里表示使用了redis.windows.conf这个配置文件的开启方式,即:开启redis-server服务,但是这个服务器使用了redis.windows.conf这个配置文件)

            //1.0开启Redis的客户端,引入 using ServiceStack.Redis;命名空间  (连接服务器)
            using (RedisClient client = new RedisClient("127.0.0.1", 6379))
            {
                //client.Password = "123456"; //如果连接Redis的redis.windows.conf文件中的配置了访问密码,则在这设置将Password设为它的访问密码

                //1.0----------------------------------
                //将数据存储到了Redis服务器中
                client.Set<string>("name", "zhangshang");

                //获取数据
                string name = client.Get<string>("name");


                //删除key为蜀国的数据
                client.Remove("蜀国");
                //client.RemoveAllFromList("蜀国");或者移除key为蜀国的集合数据。


                
                //2.0---------------------------------
                //将数据存入到同一个key中,以list集合的方式存储。(看它如何在同一个key中添加不同的数据)
                client.AddItemToList("蜀国", "刘备");
                client.AddItemToList("蜀国", "关羽");
                client.AddItemToList("蜀国", "张飞");
                client.AddItemToList("蜀国", "张飞");

                //第一种获取数据的方式 (这里是获取key=“蜀国”的数据; 注意:这个key有两个值为“张飞”的数据)
                List<string> list = client.GetAllItemsFromList("蜀国");
                list.ForEach(r => Console.WriteLine(r)); //输出:刘备 关羽 张飞 张飞

                //第二种获取数据的方式
                int listCount = (int)client.GetListCount("蜀国"); //获取key=“蜀国”的数据总条数 4
                for (int i = 0; i < listCount; i++)
                {
                    Console.WriteLine(client.GetItemFromList("蜀国", i));
                }


                //3.0----------------------------------Set(消重)  
                //用消重的方式,将数据存储到Redis服务器中
                client.AddItemToSet("魏国", "曹操");
                client.AddItemToSet("魏国", "曹操");
                client.AddItemToSet("魏国", "曹植");

                //获取数据
                HashSet<string> ha = client.GetAllItemsFromSet("魏国"); //它返回的是一个HashSet的集合
                List<string> list1 = ha.ToList(); //转成List
                list1.ForEach(r => Console.WriteLine(r)); //输出:曹操 曹植  (注意:因为我们写入了两个曹操,但是这里使用了Set去重,数以只输出了一个曹操)


                //4.0----------------------------------队列(队列的特点:先进先出)

                client.EnqueueItemOnList("吴国", "孙坚");
                client.EnqueueItemOnList("吴国", "孙策");
                client.EnqueueItemOnList("吴国", "周瑜");
                int clistCount = (int)client.GetListCount("吴国"); //获取key=“吴国”的数据总条数 3
                for (int i = 0; i < clistCount; i++)
                {
                    //出队列(出了对列的数据项,都会被删除,所以如果一个数据项出了对列后,那么Redis里面就会被删除)
                    Console.WriteLine(client.DequeueItemFromList("吴国"));
                }

                //为了测试出队列的数据项是否被删除,我们来做一个检测
                if (client.GetAllItemsFromList("吴国").Any() == false)
                {
                    Console.WriteLine("已经全部出队了,没有数据了");
                }

                Console.ReadKey();

            }

        }
    }
}

Memcached

Memcached官方网站是http://memcached.org/downloads 大家下载的最新稳定版memcached-1.4.5可以在LINUX和UNIX下顺利编译。

内存处理原理

Memcached 是一个高性能的分布式内存对象缓存系统。它通过将数据缓存在内存中来减少对数据库和文件系统的访问,减轻数据库及操作系统的负担,提高应用系统的速度。

1、Memcache主要是作为一个Socket服务器端,用于接受客户端链接,并发来存储,获取数据的命令。

2、Memcache作为一个内存管理器,我们都知道Memcache是以键值对来存储数据的,而这些数据都是存储在内存中的,那如何将数据以最合理的方式存放到内存中呢?

Memcache一开始就会对内存进行分块处理,比如你的缓存服务器的内存是64GB,那么它一开始就将这64GB分为很多不同大小的块,有大块的,有小块的。

假设我们要存储一个{key:"k1",value:"张三"} 这样的键值对,那么Memcache会去内存中寻找那个刚刚能够装的下这条数据的内存(即,寻找最适合存储这条数据的内存,如果这块内存稍微大于这条数据,(即:寻找到能存储这条数据的最小内存装下这条数据还有剩余),那么这多出来的这些内存也不会重新被分配,剩余就让它剩余,这就解决了

分布式缓存的内存碎片化的问题,但是也带来一点点内存的浪费,但是优势大于劣势。)

Memcache是没有提供监控数据过期的机制的,而是惰性的,只有当查询到某个Key数据时,如果发现过期了,那么就直接删除,腾出内存。

Memcache使用内存的优先级是:优先使用闲置的内存--->如果没有闲置的内存了,再删除过期的数据,腾出内存,再使用---->如果连过期的数据都没有了,就删除最少访问的那部分数据,腾出内存空间,再使用。

Memcache集群搭建原理

Memcache服务器端本身并没有提供集群功能,而是通过客户端的驱动程序来实现集群的配置。

客户端实现集群的原理:首先客户端创建一个多台集缓存服务器器的 ip和端口的数组  例如: string[] serverList={"202.10.1.199:112211","202.10.1.198:112211"}

然后客户端驱动程序在写入之前,首先对Key做一致性哈希算法处理,得到哈希值后对总的缓存服务器的数据进行取余,然后就选择余数对应的缓存服务器

首先去下载一个Memcached包 (我下载的是windows版)解压后我放在E盘根目录下。

下载下来是以下这样的:

现在我们将Memcache服务安装到Windows本地里面去

打开cmd,以管理员身份运行

我们可以打开windows服务(右键我的电脑-->-管理--->服务和应用程序--->服务)查询是否有开启了Memcached服务(看它的状态是否显示“已启动”,启动类型是否为“自动”)

当然我们也可以用telnet来测试下到底是否已经开启了。

打开一个新的cmd(以管理员身份运行)然后输入telnet  127.0.0.1 11211 (因为是在我本机上测试,所以IP就是我本地的IP,所以我就填127.0.0.1了,Memcached的默认端口就是11211,所以这里的端口号就是11211

输入stats 查看Memcached服务器的状态

当然我们也可以关闭服务,和卸载服务

以上是服务端部署并测试完毕后。我们来在再C#中如何来操作   请参考:.net/c# memcached 获取所有缓存键(keys)

首先我们需要下载Memcached客户端包  下载地址为:https://sourceforge.net/projects/memcacheddotnet/

文件包下载下来后,我们将它解压,然后再E:\memcacheddotnet_clientlib-1.1.5\memcacheddotnet\trunk\clientlib\src\clientlib\bin\2.0\Release 目录下将里面的4个dll文件+1个pdb文件拷贝到我们项目下,并引用到项目中(我们可以在项目中添加一个Lib文件夹,用来存储这些程序集)

using Memcached.ClientLibrary;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MemcachedDemo.Controllers
{
    public class MemcacheController : Controller
    {
        //
        // GET: /Memcache/

        public ActionResult Index()
        {
            //初始化Memcached服务器端的集群列表(即:在客户端构建Memcached服务器集群)
            string[] serverList = { "127.0.0.1:11211", "192.168.1.100:11211" };
            SockIOPool pool = SockIOPool.GetInstance("test");

            //设置怎么
            pool.SetServers(serverList);
            pool.Initialize();//初始化

            //创建一个Memcached客户端的代理类对象
            MemcachedClient client = new MemcachedClient();
            client.PoolName = "test";
            client.EnableCompression = false; //是否启用压缩


            client.Add("K1", "张三");
            client.Set("K1", "更新张三"); //如果有存在K1则更新K1的值,如果不存在则新增这个K1
            client.Set("K2", "李四", DateTime.Now.AddMinutes(30)); //新增一个键为K2的键值对,并将它的过期时间设为30分钟
            client.Delete("K1"); //删除K1

            string A = client.Get("K1").ToString(); //获取K1

            pool.Shutdown(); //关闭连接池      

            return View();
        }

    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值