当前位置: > Linux集群 > Memcached >

Linux下MemCached安装及c#客户端调用

时间:2016-11-24 23:43来源:linux.it.net.cn 作者:IT

一、Linux下MemCached安装和启动

如果是centos可以yum安装

# yum install libevent-devel

如果不支持yum的系统,可以这样装libevent

# cd /usr/local/src 
# wget http://www.monkey.org/~provos/libevent-1.4.12-stable.tar.gz 
# tar vxf libevent-1.4.12-stable.tar.gz 
# cd libevent-1.4.12 
# ./configure --prefix=/usr/local/libevent 
# make && make install

继续安装memcached

# cd /usr/local/src 
# wget http://cloud.github.com/downloads/saberma/saberma.github.com/memcached-1.4.4.tar.gz 
# tar vxf memcached-1.4.4.tar.gz 
# cd memcached-1.4.4 
# ./configure --prefix=/usr/local/memcached 
# make && make install

 

安装完后启动memcached并分配1024m内存

/usr/local/memcached/bin/memcached -d -m 1024 –l 10.32.33.120 -p 11211 -u root

-d选项是启动一个守护进程, 
-m是分配给Memcache使用的内存数量,单位是MB,我这里是10MB, 
-u是运行Memcache的用户,我这里是root, 
-l是监听的服务器IP地址,如果有多个地址的话,我这里指定了服务器的IP地址10.32.33.120, 
-p是设置Memcache监听的端口,我这里设置了12000,最好是1024以上的端口, 
-c选项是最大运行的并发连接数,默认是1024,我这里设置了256,按照你服务器的负载量来设定, 
-P是设置保存Memcache的pid文件,我这里是保存在 /tmp/memcached.pid,

将memcached加入启动项

# vi /etc/rc.d/rc.local

在最后加入

/usr/local/memcached/bin/memcached -d -m 1024 –l 10.32.33.120 -p 11211 -u root

按Esc键,再输入

:wq

保存退出

 

查看是否启动memcached

获取运行状态:echo stats | nc 10.32.33.120 11211(可以查看出pid) 或使用ps -ef|grep memcached

如果要结束Memcache进程,执行:

# kill `cat /tmp/memcached.pid`

也可以

#kill –9 进程号

二、连接到 memcached

连接到 memcached: 
telnet ip 端口,如telnet 10.32.33.120 11211 
stats查看状态,flush_all:清楚缓存 
查看memcached状态的基本命令,通过这个命令可以看到如下信息: 
STAT pid 22459 进程ID 
STAT uptime 1027046 服务器运行秒数 
STAT time 1273043062 服务器当前unix时间戳 
STAT version 1.4.4 服务器版本 
STAT pointer_size 64 操作系统字大小(这台服务器是64位的) 
STAT rusage_user 0.040000 进程累计用户时间 
STAT rusage_system 0.260000 进程累计系统时间 
STAT curr_connections 10 当前打开连接数 
STAT total_connections 82 曾打开的连接总数 
STAT connection_structures 13 服务器分配的连接结构数 
STAT cmd_get 54 执行get命令总数 
STAT cmd_set 34 执行set命令总数 
STAT cmd_flush 3 指向flush_all命令总数 
STAT get_hits 9 get命中次数 
STAT get_misses 45 get未命中次数 
STAT delete_misses 5 delete未命中次数 
STAT delete_hits 1 delete命中次数 
STAT incr_misses 0 incr未命中次数 
STAT incr_hits 0 incr命中次数 
STAT decr_misses 0 decr未命中次数 
STAT decr_hits 0 decr命中次数 
STAT cas_misses 0 cas未命中次数 
STAT cas_hits 0 cas命中次数 
STAT cas_badval 0 使用擦拭次数 
STAT auth_cmds 0 
STAT auth_errors 0 
STAT bytes_read 15785 读取字节总数 
STAT bytes_written 15222 写入字节总数 
STAT limit_maxbytes 1048576 分配的内存数(字节) 
STAT accepting_conns 1 目前接受的链接数 
STAT listen_disabled_num 0 
STAT threads 4 线程数 
STAT conn_yields 0 
STAT bytes 0 存储item字节数 
STAT curr_items 0 item个数 
STAT total_items 34 item总数 
STAT evictions 0 为获取空间删除item的总数

三、c#调用

MemCache管理操作类,MemCachedManager.cs文件:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
using System;
using System.Collections;
using System.Data;
using System.Data.Common;
using System.IO;
using Memcached.ClientLibrary;
namespace Plugin.Cache
{
    /// <summary>
    /// MemCache管理操作类
    /// </summary>
    public sealed class MemCachedManager
    {
        #region 静态方法和属性
        private static MemcachedClient mc = null;
        private static SockIOPool pool = null;
        private static string[] serverList = null;
        private static MemCachedConfigInfo memCachedConfigInfo = MemCachedConfig.GetConfig();
 
        #endregion
 
        static MemCachedManager()
        {
            CreateManager();
        }
 
        private static void CreateManager()
        {
            serverList = memCachedConfigInfo.ServerList;
            pool = SockIOPool.GetInstance(memCachedConfigInfo.PoolName);
            pool.SetServers(serverList);
            pool.InitConnections = memCachedConfigInfo.IntConnections;//初始化链接数
            pool.MinConnections = memCachedConfigInfo.MinConnections;//最少链接数
            pool.MaxConnections = memCachedConfigInfo.MaxConnections;//最大连接数
            pool.SocketConnectTimeout = memCachedConfigInfo.SocketConnectTimeout;//Socket链接超时时间
            pool.SocketTimeout = memCachedConfigInfo.SocketTimeout;// Socket超时时间
            pool.MaintenanceSleep = memCachedConfigInfo.MaintenanceSleep;//维护线程休息时间
            pool.Failover = memCachedConfigInfo.FailOver; //失效转移(一种备份操作模式)
            pool.Nagle = memCachedConfigInfo.Nagle;//是否用nagle算法启动socket
            pool.HashingAlgorithm = HashingAlgorithm.NewCompatibleHash;
 
            pool.Initialize();
 
            mc = new MemcachedClient();
            mc.PoolName = memCachedConfigInfo.PoolName;
            mc.EnableCompression = false;
        }
 
        /// <summary>
        /// 缓存服务器地址列表
        /// </summary>
        public static string[] ServerList
        {
            set
            {
                if (value != null)
                    serverList = value;
            }
            get { return serverList; }
        }
 
        /// <summary>
        /// 客户端缓存操作对象
        /// </summary>
        public static MemcachedClient CacheClient
        {
            get
            {
                if (mc == null)
                    CreateManager();
 
                return mc;
            }
        }
 
        public static void Dispose()
        {
            if (pool != null)
                pool.Shutdown();
        }
 
    }
}

 

cache操作接口类ICacheStrategy.cs(为了方便扩展其他的cache):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using System;
using System.Text;
 
namespace Plugin.Cache
{
    /// <summary>
    /// 公共缓存策略接口
    /// </summary>
    public interface ICacheStrategy
    {
        /// <summary>
        /// 添加指定ID的对象
        /// </summary>
        /// <param name="objId">缓存键</param>
        /// <param name="o">缓存对象</param>
        void AddObject(string objId, object o);
      
        /// <summary>
        /// 移除指定ID的对象
        /// </summary>
        /// <param name="objId">缓存键</param>
        void RemoveObject(string objId);
        /// <summary>
        /// 返回指定ID的对象
        /// </summary>
        /// <param name="objId">缓存键</param>
        /// <returns></returns>
        object RetrieveObject(string objId);
        /// <summary>
        /// 到期时间,单位:秒
        /// </summary>
        int TimeOut { set;get;}
   }
}

MemCached.cs类

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
using System;
using System.Web;
using System.Collections;
using System.Web.Caching;
 
namespace Plugin.Cache
{
    /// <summary>
    /// 默认缓存管理类,默认用memcached
    /// </summary>
    public class MemCached : ICacheStrategy
    {  
        /// <summary>
        /// 设置到期相对时间[单位: 秒]
        /// </summary>
        public int TimeOut { set; get; }
        
        /// <summary>
        /// 加入当前对象到缓存中
        /// </summary>
        /// <param name="objId">对象的键值</param>
        /// <param name="o">缓存的对象</param>
        public virtual void AddObject(string objId, object o)
        {
            if (TimeOut > 0)
            {
                MemCachedManager.CacheClient.Set(objId, o, System.DateTime.Now.AddSeconds(TimeOut));
            }
            else
            {
                MemCachedManager.CacheClient.Set(objId, o);
            }
        }
 
        /// <summary>
        /// 删除缓存对象
        /// </summary>
        /// <param name="objId">对象的关键字</param>
        public virtual void RemoveObject(string objId)
        {
            if (MemCachedManager.CacheClient.KeyExists(objId))
                MemCachedManager.CacheClient.Delete(objId);
        }
 
 
        /// <summary>
        /// 返回一个指定的对象
        /// </summary>
        /// <param name="objId">对象的关键字</param>
        /// <returns>对象</returns>
        public virtual object RetrieveObject(string objId)
        {
            return MemCachedManager.CacheClient.Get(objId);
        }
 
    }
}

 

实体类MemCachedConfigInfo.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
using Yintai.Plugin.Common;
 
/// <summary>
/// MemCached配置信息类文件
/// </summary>
 
namespace Plugin
{
    public class MemCachedConfigInfo
    {
        private string[] _serverList;
        /// <summary>
        /// 链接地址
        /// </summary>
        public string[] ServerList
        {
            get { return _serverList; }
            set { _serverList = value; }
        }
 
        private string _poolName;
        /// <summary>
        /// 链接池名称
        /// </summary>
        public string PoolName
        {
            get { return string.IsNullOrEmpty(_poolName) ? "Yintai.Plugin.Cache.MemCached" : _poolName; }
            set { _poolName = value; }
        }
 
        private int _intConnections;
 
        /// <summary>
        /// 初始化链接数
        /// </summary>
        public int IntConnections
        {
            get { return _intConnections > 0 ? _intConnections : 3; }
            set { _intConnections = value; }
        }
 
        private int _minConnections;
 
        /// <summary>
        /// 最少链接数
        /// </summary>
        public int MinConnections
        {
            get { return _minConnections > 0 ? _minConnections : 3; }
            set { _minConnections = value; }
        }
 
        private int _maxConnections;
 
        /// <summary>
        /// 最大连接数
        /// </summary>
        public int MaxConnections
        {
            get { return _maxConnections > 0 ? _maxConnections : 5; }
            set { _maxConnections = value; }
        }
 
        private int _socketConnectTimeout;
 
        /// <summary>
        /// Socket链接超时时间
        /// </summary>
        public int SocketConnectTimeout
        {
            get { return _socketConnectTimeout > 1000 ? _socketConnectTimeout : 1000; }
            set { _socketConnectTimeout = value; }
        }
 
        private int _socketTimeout;
 
        /// <summary>
        /// socket超时时间
        /// </summary>
        public int SocketTimeout
        {
            get { return _socketTimeout > 1000 ? _maintenanceSleep : 3000; }
            set { _socketTimeout = value; }
        }
 
        private int _maintenanceSleep;
 
        /// <summary>
        /// 维护线程休息时间
        /// </summary>
        public int MaintenanceSleep
        {
            get { return _maintenanceSleep > 0 ? _maintenanceSleep : 30; }
            set { _maintenanceSleep = value; }
        }
 
        private bool _failOver;
 
        /// <summary>
        /// 链接失败后是否重启,详情参见http://baike.baidu.com/view/1084309.htm
        /// </summary>
        public bool FailOver
        {
            get { return _failOver; }
            set { _failOver = value; }
        }
 
        private bool _nagle;
 
        /// <summary>
        /// 是否用nagle算法启动socket
        /// </summary>
        public bool Nagle
        {
            get { return _nagle; }
            set { _nagle = value; }
        }
    }
}

 

实现代码完了,下面就是把配置文件memcached.config反序列化成实体方法

用MemCachedConfig.cs实现配置文件的载入和读取LoadConfig是载入配置,SetConfig是保存配置,GetConfig是获取配置,其中用了了序列化和反序列化

MemCachedConfig.cs文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Web;
using Plugin.Cache;
using Plugin.Common;
 
 
namespace Plugin
{
    public class MemCachedConfig
    {
        private static object _lockHelper = new object();
        private static MemCachedConfigInfo config = null;
 
        public static void LoadConfig(string configfilepath)
        {
            if (config == null)
            {
                lock (_lockHelper)
                {
                    if (config == null)
                    {
                        config = (MemCachedConfigInfo)SerializationHelper.Load(typeof(MemCachedConfigInfo), configfilepath);
                    }
                }
            }
        }
 
        /// <summary>
        /// 获取配置
        /// </summary>
        /// <param name="anConfig"></param>
        public static MemCachedConfigInfo GetConfig()
        {
            return config;
        }
 
        #region 私有方法
        public static void SetConfig(MemCachedConfigInfo verifyImageServiceInfoList, string configfilepath)
        {
            SerializationHelper.Save(verifyImageServiceInfoList, configfilepath);
        }
 
        #endregion
    }
}

SerializationHelper.cs代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
using System;
using System.IO;
using System.Xml.Serialization;
using System.Xml;
using System.Collections.Generic;
using System.Text;
 
namespace Plugin.Common
{
    /// <summary>
    /// SerializationHelper 的摘要说明。
    /// </summary>
    public class SerializationHelper
    {
        private SerializationHelper()
        {}
 
        private static Dictionary<int, XmlSerializer> serializer_dict = new Dictionary<int, XmlSerializer>();
 
        public static XmlSerializer GetSerializer(Type t)
        {
            int type_hash = t.GetHashCode();
 
            if (!serializer_dict.ContainsKey(type_hash))
                serializer_dict.Add(type_hash, new XmlSerializer(t));
 
            return serializer_dict[type_hash];
        }
 
 
        /// <summary>
        /// 反序列化
        /// </summary>
        /// <param name="type">对象类型</param>
        /// <param name="filename">文件路径</param>
        /// <returns></returns>
        public static object Load(Type type, string filename)
        {
            FileStream fs = null;
            try
            {
                // open the stream...
                fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                XmlSerializer serializer = new XmlSerializer(type);
                return serializer.Deserialize(fs);
            }
            catch(Exception ex)
            {
                throw ex;
            }
            finally
            {
                if(fs != null)
                    fs.Close();
            }
        }
 
 
        /// <summary>
        /// 序列化
        /// </summary>
        /// <param name="obj">对象</param>
        /// <param name="filename">文件路径</param>
        public static bool Save(object obj, string filename)
        {
            bool success = false;
 
            FileStream fs = null;
            // serialize it...
            try
            {
                fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
                XmlSerializer serializer = new XmlSerializer(obj.GetType());
                serializer.Serialize(fs, obj);
                success = true;
            }
            catch(Exception ex)
            {
                throw ex;
            }
            finally
            {
                if(fs != null)
                    fs.Close();
            }
            return success;
 
        }
 
        /// <summary>
        /// xml序列化成字符串
        /// </summary>
        /// <param name="obj">对象</param>
        /// <returns>xml字符串</returns>
        public static string Serialize(object obj)
        {
            string returnStr = "";
            XmlSerializer serializer = GetSerializer(obj.GetType());
            MemoryStream ms = new MemoryStream();
            XmlTextWriter xtw = null;
            StreamReader sr = null;
            try
            {
                xtw = new System.Xml.XmlTextWriter(ms, Encoding.UTF8);
                xtw.Formatting = System.Xml.Formatting.Indented;
                serializer.Serialize(xtw, obj);
                ms.Seek(0, SeekOrigin.Begin);
                sr = new StreamReader(ms);
                returnStr = sr.ReadToEnd();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (xtw != null)
                    xtw.Close();
                if (sr != null)
                    sr.Close();
                ms.Close();
            }
            return returnStr;
 
        }
 
        public static object DeSerialize(Type type, string s)
        {
            byte[] b = System.Text.Encoding.UTF8.GetBytes(s);
            try
            {
                XmlSerializer serializer = GetSerializer(type);
                return serializer.Deserialize(new MemoryStream(b));
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}

最后配置文件类似这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0"?>
<MemCachedConfigInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <ServerList>
    <string>10.32.33.120:11211</string>
  </ServerList>
  <PoolName>Plugin.Cache.MemCached</PoolName>
  <IntConnections>3</IntConnections>
  <MinConnections>3</MinConnections>
  <MaxConnections>5</MaxConnections>
  <SocketConnectTimeout>1000</SocketConnectTimeout>
  <SocketTimeout>30</SocketTimeout>
  <MaintenanceSleep>30</MaintenanceSleep>
  <FailOver>true</FailOver>
  <Nagle>false</Nagle>
</MemCachedConfigInfo>

 

使用时调用方法:

MemCachedConfig.LoadConfig(Server.MapPath("/config/memcached.config"));

这个方法通过LoadConfig把配置加载进来,反序列化成MemCachedConfigInfo实体并放入私有静态变量config 中,并通过GetConfig() 获取config,然后MemCachedManager类通过private static MemCachedConfigInfo memCachedConfigInfo = MemCachedConfig.GetConfig();方法获取到配置了。



(责任编辑:IT)
------分隔线----------------------------