• 数据库缓存之Memcache知识点


    Memcache知识点总结:

    一、Memcache安装及使用

    参考地址:https://www.jb51.net/article/66525.htm

    1.将下载的Memcache安装文件放到某盘下,如下:

     dos命令下运行命令进入该目录下:

     

     2.Memcached参数说明:

    memcached -d start|stop|shutdown|restart|uninstall|install 启动|停止|关闭|重启|卸载|安装。

    -p 监听的端口
    -l 连接的IP地址, 默认是本机
    -d start 启动memcached服务
    -d restart 重起memcached服务
    -d stop|shutdown 关闭正在运行的memcached服务
    -d install 安装memcached服务
    -d uninstall 卸载memcached服务
    -u 以的身份运行 (仅在以root运行的时候有效)
    -m 最大内存使用,单位MB。默认64MB
    -M 内存耗尽时返回错误,而不是删除项
    -c 最大同时连接数,默认是1024
    -f 块大小增长因子,默认是1.25
    -n 最小分配空间,key+value+flags默认是48
    -h 显示帮助

    服务器操作完成后,我们可以在本机telnet 到服务测试一个下。(如果提示telnet命令不存在,需要去控件面板开启windows的tel服务功能, win7的开启tel功能操作步骤是:【控制面板】->【程序和功能】->【打开或关闭window功能】,然后找到并勾选tel相关即可。其他window系统步骤类似。)

    测试telnet是否正常运行 telnet 172.21.0.192 11211 

    进入后先按ctrl+]启动回示功能,否则无法看到输入信息。回示功能启动成功后如下图:

    然后按回车输入参数stats:

     

    安装和测试工作已完成..

    实例代码

    有很多C#版本的Memcached客户端程序。在这里我们使用的是Memcached.ClientLibrary.dll客户端调用方法,调用需要二个DLL:

    Memcached.ClientLibrary.dll (Memcached客户端类库)

    log4net.dll (log4net是为Memcached提供日志记录) 

    在项目中引用这个二个dll,引用log4net.dll后还需进行一系列配置工作。

    注意:Memcached.ClientLibrary.dll和log4net.dll有版本对应关系。

    2.如果使用WinForm或控制台应用程序把log4net的配置文件独立出现,和写在App.config里面需要小小设置一下。

    如图:Log4Net.config属性“复制到输出目录”:“始终复制”。不然在bin目录下找不到对应配置信息会产生报错。

     项目目录如下:

     

     LogConfig中的Log4Net.config源码如下:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    <configSections>
    <!--添加自定义节点:log4net type:解析类名,程序集名(log4net.dll)-->
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
    </configSections>

    <log4net>
    <!--定义输出到文件中-->
    <appender name="Log4Net_INFO" type="log4net.Appender.RollingFileAppender">
    <!--定义文件存放位置-->
    <file value="D:/log4net/"/>
    <!--是否追加到文件,默认为true,通常无需设置-->
    <appendToFile value="true"/>
    <RollingStyle value="Date"/>
    <!--日期的格式,每天换一个文件记录,如不设置则永远只记录一天的日志,需设置-->
    <DatePattern value="INFO_yyyyMMdd&quot;.log&quot;" />
    <!--日志文件名是否为静态-->
    <StaticLogFileName value="false"/>
    <!--多线程时采用最小锁定-->
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <!--布局(向用户显示最后经过格式化的输出信息)-->
    <layout type="log4net.Layout.PatternLayout">
    <!--
    %m(message):输出的日志消息,如ILog.Debug(…)输出的一条消息
    %n(new line):换行
    %d(datetime):输出当前语句运行的时刻
    %r(run time):输出程序从运行到执行到当前语句时消耗的毫秒数
    %t(thread id):当前语句所在的线程ID
    %p(priority): 日志的当前优先级别,即DEBUG、INFO、WARN…等
    %c(class):当前日志对象的名称,例如:
    %L:输出语句所在的行号
    %F:输出语句所在的文件名
    %-数字:表示该项的最小长度,如果不够,则用空格填充
    -->
    <Header value="[Header]&#13;&#10;"/>
    <Footer value="[Footer]&#13;&#10;"/>
    <!--正文-->
    <ConversionPattern value="记录时间:%date 线程ID:[%thread] 日志级别:%-5level 出错类:%logger property:[%property{NDC}] - 错误描述:%message%newline" />
    </layout>
    </appender>


    <!--<appender></appender>定义输出信息设置节点,决定日志输出的方式(可设置多个节点,如对INFO,ERROR等设置不同的输出方式)-->
    <appender name="Log4Net_ERROR" type="log4net.Appender.RollingFileAppender">
    <file value="D:/log4net/"/>
    <appendToFile value="true"/>
    <RollingStyle value="Date"/>
    <DatePattern value="ERROR_yyyyMMdd&quot;.log&quot;" />
    <StaticLogFileName value="false"/>
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <layout type="log4net.Layout.PatternLayout">
    <Header value="[Header]&#13;&#10;"/>
    <Footer value="[Footer]&#13;&#10;"/>
    <!--正文-->
    <ConversionPattern value="记录时间:%date 线程ID:[%thread] 日志级别:%-5level 出错类:%logger property:[%property{NDC}] - 错误描述:%message%newline" />
    </layout>
    </appender>

    <!--<root></root>定义日志的输出媒介-->
    <root>
    <level value="ERROR"/>
    <appender-ref ref="Log4Net_ERROR" />

    <level value="INFO"/>
    <appender-ref ref="Log4Net_INFO" />
    </root>

    </log4net>

    </configuration>

     program.cs中源码如下:

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using Memcached.ClientLibrary;
    using MemcacheProject.Model;

    namespace MemcacheProject
    {
    /*
    * Memcache项目实例应用
    *
    * 需引用Memcached.ClientLibrary.dll、 log4net.dll
    * 注明:在项目的nuget中下载Memcached.ClientLibrary时log4net.dll也会一并下载
    * 学习地址:https://www.jb51.net/article/66525.htm
    *
    */
    class Program
    {
    static void Main(string[] args)
    {
    Program pro =new Program();
    pro.OperateMemcacheMethod();
    }
    /// <summary>
    /// memcache的基本操作:增,删,查,改,设置过期时间
    /// </summary>
    public void OperateMemcacheMethod()
    {

    //参数设置
    string SockIOPoolName = "Test_SockIOPoolName";
    string[] MemcacheServiceList = {"127.0.0.1:11211" };//11211是端口号

    //设置连接池
    SockIOPool SPool = SockIOPool.GetInstance(SockIOPoolName);
    SPool.SetServers(MemcacheServiceList);
    SPool.Initialize();

    //实例化
    MemcachedClient MClient = new MemcachedClient();
    MClient.PoolName = SockIOPoolName;

    Console.WriteLine("1.创建memcache缓存Hello World");
    MClient.Add("key1001", "Hello World");
    Console.WriteLine("2.查询缓存信息{0}",MClient.Get("key1001"));

    Console.WriteLine("3.修改memcache缓存Hello World");
    MClient.Set("key1001","Hello World -修改版");
    Console.WriteLine("4.查询缓存信息{0}",MClient.Get("key1001"));

    //删除memcache缓存
    if (MClient.KeyExists("key1001"))
    {
    Console.WriteLine("5.删除memcache缓存");
    MClient.Delete("key1001");
    }

    //缓存删除后判断是否仍然存在
    if (MClient.KeyExists("key1001"))
    {
    Console.WriteLine(MClient.Get("key1001"));
    }
    else
    {
    Console.WriteLine("6.缓存已删除");
    }

    //添加对象值到缓存
    Student stud= new Student()
    {
    id ="10001",
    name="张三"
    };
    MClient.Add("student", stud);
    Student Get_stud = MClient.Get("student") as Student;
    Console.WriteLine("7.缓存实体对象:{0}{1}", Get_stud.id, Get_stud.name);

    //设置过期时间
    MClient.Add("key1002","我已设置过期时间1分钟",DateTime.Now.AddMinutes(1));
    while (true)
    {
    if (MClient.KeyExists("key1002"))
    {
    Console.WriteLine("key:key1002 Vlaue:{0},当前时间:{1}",MClient.Get("key1002"),DateTime.Now);
    Thread.Sleep(20000);
    }
    else
    {
    Console.WriteLine("key:key1002 我已过期,当前时间:{0}",DateTime.Now);
    Console.WriteLine("key:key1002 Vlaue:{0},当前时间:{1}", MClient.Get("key1002"), DateTime.Now);
    Console.ReadKey();
    break;
    }

    }
    }
    /// <summary>
    /// 多个memcache操作
    /// </summary>
    public void OperateManyMemcacheMethod()
    {
    //参数
    string[] MemcacheServiceList = {"10.3.90.1:11211", "10.3.90.2:11211", "10.3.90.3:11211"};

    //设置连接池
    SockIOPool SPool = SockIOPool.GetInstance();
    SPool.SetServers(MemcacheServiceList);
    SPool.Initialize();

    MemcachedClient MClient = new MemcachedClient();
    MClient.FlushAll();

    int count = 5;
    var time = Stopwatch.StartNew();
    for (int i=0;i<count;i++)
    {
    MClient.Add(i.ToString(), "value" + i);
    }
    Console.WriteLine("memcached缓存创建成功.耗时:{0}",time.ElapsedTicks);

    time = Stopwatch.StartNew();
    for (int i=0;i<count;i++)
    {
    if (MClient.KeyExists(i.ToString()))
    {
    Console.WriteLine("key:{0}.value:{1}",i,MClient.Get(i.ToString()));
    }
    else
    {
    Console.WriteLine("-----------未能查询到数据key:{0}----------",i);
    }
    }
    Console.WriteLine("memcached缓存数据查询完成,耗时:{0}",time.ElapsedTicks);
    SPool.Shutdown();
    }
    }
    }

     

     项目源码:

    https://files-cdn.cnblogs.com/files/newcapecjmc/MemcacheProject.rar

     附:Log4Net日志配置:

    参考地址:https://www.jb51.net/article/66526.htm

    1.下载log4net.dll 下载地址[http://logging.apache.org/log4net/download_log4net.cgi]

    下载文件:log4net-1.2.13-bin-newkey.zip。 解压选择对应的net版本找到log4net.dll。

    2.在项目中引用log4net.dll。

    实例代码

    准备工作完成后我们来看下实例代码 ,首先在项目中创建一个文件夹LogConfig。把有关log4net的一些配置文件和类都放在这个文件夹里面。

    WEB网站为例,在项目LogConfig文件夹中创建Log4Net.config配置文件。

    Log4Net.config配置文件源码:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    <configSections>
    <!--添加自定义节点:log4net type:解析类名,程序集名(log4net.dll)-->
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
    </configSections>

    <log4net>
    <!--定义输出到文件中-->
    <appender name="Log4Net_INFO" type="log4net.Appender.RollingFileAppender">
    <!--定义文件存放位置-->
    <file value="D:/log4net/"/>
    <!--是否追加到文件,默认为true,通常无需设置-->
    <appendToFile value="true"/>
    <RollingStyle value="Date"/>
    <!--日期的格式,每天换一个文件记录,如不设置则永远只记录一天的日志,需设置-->
    <DatePattern value="INFO_yyyyMMdd&quot;.log&quot;" />
    <!--日志文件名是否为静态-->
    <StaticLogFileName value="false"/>
    <!--多线程时采用最小锁定-->
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <!--布局(向用户显示最后经过格式化的输出信息)-->
    <layout type="log4net.Layout.PatternLayout">
    <!--
    %m(message):输出的日志消息,如ILog.Debug(…)输出的一条消息
    %n(new line):换行
    %d(datetime):输出当前语句运行的时刻
    %r(run time):输出程序从运行到执行到当前语句时消耗的毫秒数
    %t(thread id):当前语句所在的线程ID
    %p(priority): 日志的当前优先级别,即DEBUG、INFO、WARN…等
    %c(class):当前日志对象的名称,例如:
    %L:输出语句所在的行号
    %F:输出语句所在的文件名
    %-数字:表示该项的最小长度,如果不够,则用空格填充
    -->
    <Header value="[Header]&#13;&#10;"/>
    <Footer value="[Footer]&#13;&#10;"/>
    <!--正文-->
    <ConversionPattern value="记录时间:%date 线程ID:[%thread] 日志级别:%-5level 出错类:%logger property:[%property{NDC}] - 错误描述:%message%newline" />
    </layout>
    </appender>

    <appender name="Log4Net_ERROR" type="log4net.Appender.RollingFileAppender">
    <file value="D:/log4net/"/>
    <appendToFile value="true"/>
    <RollingStyle value="Date"/>
    <DatePattern value="ERROR_yyyyMMdd&quot;.log&quot;" />
    <StaticLogFileName value="false"/>
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <layout type="log4net.Layout.PatternLayout">
    <Header value="[Header]&#13;&#10;"/>
    <Footer value="[Footer]&#13;&#10;"/>
    <!--正文-->
    <ConversionPattern value="记录时间:%date 线程ID:[%thread] 日志级别:%-5level 出错类:%logger property:[%property{NDC}] - 错误描述:%message%newline" />
    </layout>
    </appender>

    <root>
    <level value="ERROR"/>
    <appender-ref ref="Log4Net_ERROR" />

    <level value="INFO"/>
    <appender-ref ref="Log4Net_INFO" />
    </root>

    </log4net>

    </configuration>

     

    配置文件写完后我们在来写一个Helper类。同样在项目中创建一个名为LogHelper.cs的类文件

    源码如下:

    using System;
    using System.Collections.Concurrent;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using log4net;

    //指定log4net使用的config文件来读取配置信息
    [assembly: log4net.Config.XmlConfigurator(ConfigFile = @"LogConfigLog4Net.config",Watch = true)]
    namespace Log4.NetProject.LogConfig
    {
    /// <summary>
    /// 日志帮助类
    /// </summary>
    public class LogHelper
    {
    private static readonly ConcurrentDictionary<Type,ILog>
    _loggers = new ConcurrentDictionary<Type, ILog>();

    /// <summary>
    /// 1.获取记录器
    /// </summary>
    /// <param name="source"></param>
    /// <returns></returns>
    private static ILog GetLogger(Type source)
    {
    if (_loggers.ContainsKey(source))
    {
    return _loggers[source];
    }
    else
    {
    ILog logger = LogManager.GetLogger(source);
    _loggers.TryAdd(source, logger);
    return logger;
    }
    }

    /*
    * Log a message object
    */

    /// <summary>
    /// 2.调试信息
    /// </summary>
    public static void Debug(object source,string message)
    {
    Debug(source.GetType(),message);
    }
    /// <summary>
    /// 3.调试信息
    /// </summary>
    /// <param name="source"></param>
    /// <param name="message"></param>
    /// <param name="ps"></param>
    public static void Debug(object source,string message,params object[] ps)
    {
    Debug(source.GetType(),string.Format(message,ps));
    }
    /// <summary>
    /// 4.调试信息
    /// </summary>
    /// <param name="source"></param>
    /// <param name="message"></param>
    public static void Debug(Type source,string message)
    {
    ILog logger = GetLogger(source);
    if (logger.IsDebugEnabled)
    {
    logger.Debug(message);
    }
    }
    /// <summary>
    /// 5.关键信息
    /// </summary>
    public static void Info(object source, object message)
    {
    Info(source.GetType(),message);
    }
    /// <summary>
    /// 6.关键信息
    /// </summary>
    public static void Info(Type source,object message)
    {
    ILog logger = GetLogger(source);
    if (logger.IsInfoEnabled)
    {
    logger.Info(message);
    }
    }
    /// <summary>
    /// 7.警告信息
    /// </summary>
    public static void Warn(object source,object message)
    {
    Warn(source.GetType(),message);
    }
    /// <summary>
    /// 8.警告信息
    /// </summary>
    /// <param name="source"></param>
    /// <param name="message"></param>
    public static void Warn(Type source, object message)
    {
    ILog logger = GetLogger(source);
    if (logger.IsWarnEnabled)
    {
    logger.Warn(message);
    }
    }
    /// <summary>
    /// 9.错误信息
    /// </summary>
    public static void Error(object source, object message)
    {
    Error(source.GetType(), message);
    }
    /// <summary>
    /// 10.错误信息
    /// </summary>
    /// <param name="source"></param>
    /// <param name="message"></param>
    public static void Error(Type source, object message)
    {
    ILog logger = GetLogger(source);
    if (logger.IsErrorEnabled)
    {
    logger.Error(message);
    }
    }
    /// <summary>
    /// 11.失败信息
    /// </summary>
    public static void Fatal(object source, object message)
    {
    Fatal(source.GetType(), message);
    }
    /// <summary>
    /// 12.失败信息
    /// </summary>
    /// <param name="source"></param>
    /// <param name="message"></param>
    public static void Fatal(Type source, object message)
    {
    ILog logger = GetLogger(source);
    if (logger.IsFatalEnabled)
    {
    logger.Fatal(message);
    }
    }

    /*
    * Log a message object and exception
    */
    /// <summary>
    /// 调试信息
    /// </summary>
    public static void Debug(object source,object message,Exception exception)
    {
    Debug(source.GetType(),message,exception);
    }
    /// <summary>
    /// 调试信息
    /// </summary>
    public static void Debug(Type source,object message,Exception exception)
    {
    GetLogger(source).Debug(message,exception);
    }
    /// <summary>
    /// 关键信息
    /// </summary>
    public static void Info(object source, object message, Exception exception)
    {
    Info(source.GetType(), message, exception);
    }
    /// <summary>
    /// 关键信息
    /// </summary>
    public static void Info(Type source, object message, Exception exception)
    {
    GetLogger(source).Info(message, exception);
    }
    /// <summary>
    /// 警告信息
    /// </summary>
    public static void Warn(object source, object message, Exception exception)
    {
    Warn(source.GetType(), message, exception);
    }
    /// <summary>
    /// 警告信息
    /// </summary>
    public static void Warn(Type source, object message, Exception exception)
    {
    GetLogger(source).Warn(message, exception);
    }
    /// <summary>
    /// 错误信息
    /// </summary>
    public static void Error(object source, object message, Exception exception)
    {
    Error(source.GetType(), message, exception);
    }
    /// <summary>
    /// 错误信息
    /// </summary>
    public static void Error(Type source, object message, Exception exception)
    {
    GetLogger(source).Error(message, exception);
    }
    /// <summary>
    /// 失败信息
    /// </summary>
    public static void Fatal(object source, object message, Exception exception)
    {
    Fatal(source.GetType(), message, exception);
    }
    /// <summary>
    /// 失败信息
    /// </summary>
    public static void Fatal(Type source, object message, Exception exception)
    {
    GetLogger(source).Fatal(message, exception);
    }

    }
    }

    配置和Helper类都有了..现在来看看调用方法。在项目中创建一个index.aspx页面

     源码:

    LogHelper.Debug(this,"Debug");
    LogHelper.Error(this, "Error");
    LogHelper.Fatal(this, "Fatal");
    LogHelper.Info(this, "Info");
    LogHelper.Warn(this, "Warn");

     

     项目源码https://files-cdn.cnblogs.com/files/newcapecjmc/Log4.NetProject.rar

     参数说明:

    Log4Net.config是配置日志输出参数文件。在这个文件中可以到看很多配置节点,大体可以分为二个大类<configSections>...</configSections> 和 <log4net>...</log4net>。我们来看看这些节点都是啥意思。

    1:<configSections>..</configSections>:申明自定义节点log4net解析的类名和程序集名(log4net.dll)。
    2:<log4net>..</log4net>:使用log4net的配置信息都在这里设置。来重点看看都有那些设置信息,这个大节点整体也可以分为二类。

    2.1:定义输出信息设置节点<appender></appender>。
    2.2:定义日志的输出媒介<root></root>。

    配置的总体结构就是这样,下面来看一些详细内容。

    appender:决定日志输出的方式(可设置多个节点,如对INFO,ERROR等设置不同的输出方式)。

    主要包括已下几种:

    1 AnsiColorTerminalAppender:在ANSI 窗口终端写下高亮度的日志事件。
    2 AspNetTraceAppender:能用asp.net中Trace的方式查看记录的日志。
    3 BufferingForwardingAppender:在输出到子Appenders之前先缓存日志事件。
    4 ConsoleAppender:将日志输出到控制台。
    5 EventLogAppender:将日志写到Windows Event Log. 
    6 FileAppender:将日志写到文件中。
    7 LocalSyslogAppender:将日志写到local syslog service (仅用于UNIX环境下). 
    8 MemoryAppender:将日志存到内存缓冲区。
    9 NetSendAppender:将日志输出到Windows Messenger service.这些日志信息将在用户终端的对话框中显示。
    10 RemoteSyslogAppender:通过UDP网络协议将日志写到Remote syslog service。
    11 RemotingAppender:通过.NET Remoting将日志写到远程接收端。
    12 RollingFileAppender:将日志以回滚文件的形式写到文件中。(实例代码中使用的是此类型)
    13 SmtpAppender:将日志写到邮件中。
    14 TraceAppender:将日志写到.NET trace 系统。
    15 UdpAppender:将日志connectionless UDP datagrams的形式送到远程宿主或以UdpClient的形式广播。

    从上面提供的方式中可以看出能输出文件、控制台、Windows事件日志和数据库。这个可根据实际情况选择。

    代码如下:

    <appender name="Log4Net_INFO" type="log4net.Appender.RollingFileAppender">
    ...
    </appender>

    这里配置的name(“Log4Net_INFO”)会在定义日志的输出媒介中使用到。name可任意设置。

    在appender 节点中还会配置一些文件存放的地址,日志个数等信息。这些在实例代码中都在体现,这里不做说明。我们在来看看日志最后输出呈现的布局设置信息。

    <layout type="log4net.Layout.PatternLayout">
        <!--头-->
        <Header value="[Header]"/>
        <!--脚注-->
        <Footer value="[Footer]"/>
        <!--正文-->
        <ConversionPattern value="%d [%t] %-5p %c [%x] - %m%n" />
    </layout>
     

    这里配置的信息最终是日志打印出来的样式。我们可以看到这里可以设置内容头Header和尾Footer。正文ConversionPattern。在正文中有出现有 %d [%t]这些都是啥意思了表示什么。这里有一个对照表可提供参考:

    %m(message):输出的日志消息,如ILog.Debug(…)输出的一条消息 
    %n(new line):换行 
    %d(datetime):输出当前语句运行的时刻 
    %r(run time):输出程序从运行到执行到当前语句时消耗的毫秒数 
    %t(thread id):当前语句所在的线程ID 
    %p(priority): 日志的当前优先级别,即DEBUG、INFO、WARN…等 
    %c(class):当前日志对象的名称,例如:
    %L:输出语句所在的行号 
    %F:输出语句所在的文件名 
    %-数字:表示该项的最小长度,如果不够,则用空格填充

    配置的基本也就这些。下就是root的配置说明 。

    root:

    对设置输出的方式进行指定。

    <root>
       <!--批定DEBUG输出的文件形式记录日志-->
       <level value="DEBUG"/>
       <appender-ref ref="Log4Net_ERROR" />
      
      <!--批定INFO输出的文件形式记录日志-->
       <level value="INFO"/>
       <appender-ref ref="Log4Net_INFO" />
    </root>
    控制级别,由低到高: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF
    比如定义级别为INFO,则INFO级别向下的级别,比如DEBUG日志将不会被记录
    如果没有定义LEVEL的值,则缺省为DEBUG

      3.Memcached缓存过期机制:

    惰性删除:它并没有提供监控数据过期的机制,而是惰性的,当查询到某个key数据时,如果过期那么直接抛弃。

    比如键key1002在2015-04-09 13:54 :18 我设置他的值为:”我已设置过期时间1分钟“。他的过期时间为1分钟。

    等到2015-04-09 13:55 :18时数据应该过期,但在内存中还是会保存这条数据,而是等客户端来请求这条数据时判断数据是否过期。

    过期就直接删除返回空。如果内存满了memcached会把最长时间未使用到期的缓存记录给删除,腾出空间继续使用。

    4.Memcached分布存储

    下面假设memcached服务器有如下Memcache1-3 共3台,应用程序要保存键名为“tokyo”、“kanagawa”、“chiba”、“saitama”、“gunma”

    的数据

     首先向memcached中添加“toyko”。将“toyko”传给客户端程序库后,客户端实现的算法就会根据“键”来决定保存数据的memcached服务器.

    服务器选定后,即命令它保存“tokyo”及其值。

     同样,“kanagawa”、“chiba”、“saitama”、“gunma”都是先选择服务器再保存.

    接下来获取保存的数据。获取时也要将要获取的键“tokyo”传递给函数库。函数库通过与数据保存时相同的算法,根据“键”选择服务器。使用的算法相同,就能选中与保存时相同的服务器,然后发送get命令。只要数据没有因为某些原因被删除,就能获得保存的值。

     

     这样,将不同的键保存到不同的服务器上,就实现了memcached的分布式。Memcached服务器增多后,键就会分散,即使一台memcached服务器发生故障无法连接,也不会影响其他的缓存,系统依然能继续运行。

    补充:转自:https://yusi123.com/2833.html

    telnet到memcached服务器后有很多的命令可以使用,除了大家熟知的add、get、set、incr、decr、replace、delete等赋值命令外,还有一系列的获取服务器信息的命令,这部分命令都是以stats开头的。

    memcached常用的stats命令查询memcache运行状态

    1、stats :显示服务器信息、统计数据等

    1. stats
    2. STAT pid 13375
    3. STAT uptime 2147
    4. STAT time 1208694456
    5. STAT version 1.2.5
    6. STAT pointer_size 32
    7. STAT rusage_user 0.020000
    8. STAT rusage_system 0.010000
    9. STAT curr_items 0
    10. STAT total_items 0
    11. STAT bytes 0
    12. STAT curr_connections 2
    13. STAT total_connections 3
    14. STAT connection_structures 3
    15. STAT cmd_get 0
    16. STAT cmd_set 0
    17. STAT get_hits 0
    18. STAT get_misses 0
    19. STAT evictions 0
    20. STAT bytes_read 7
    21. STAT bytes_written 0
    22. STAT limit_maxbytes 67108864
    23. STAT threads 1
    24. END

    pid:守护进程的id

    uptime:进程已经运行的时间,以秒为单位

    time:当前的unix时间

    version:服务器版本

    pointer_size:操作系统默认的指针长度

    rusage_user:进程累计的user time(秒:毫秒)

    rusage_system:进程累计的system time(秒:毫秒)

    curr_items:当前的items数量

    total_items:进程启动开始存储过的items数量

    bytes:当前用于存储items的byte数量

    curr_connections:打开的连接数量

    total_connections:进程启动开始打开过的连接数量

    connection_structures:服务分配的连接结构数量

    cmd_get:提取请求次数

    cmd_set:存储请求次数

    get_hits:get命中次数

    get_misses:get未命中次数

    evictions:为了添加新item而回收的合法item数量

    bytes_read:服务从network读取的byte数量

    bytes_written:服务写入network的byte数量

    limit_maxbytes:服务可使用的用于存储数据的最大值

    threads:被请求的工作线程数量

    2、stats reset  清空统计数据

    1. stats reset
    2. RESET
    3.  
    4. stats
    5. STAT pid 2305
    6. STAT uptime 40596
    7. STAT time 1294906749
    8. STAT version 1.2.6
    9. STAT pointer_size 64
    10. STAT rusage_user 1.671745
    11. STAT rusage_system 2.803573
    12. STAT curr_items 86642
    13. STAT total_items 0
    14. STAT bytes 29865212
    15. STAT curr_connections 14
    16. STAT total_connections 0
    17. STAT connection_structures 16
    18. STAT cmd_get 0
    19. STAT cmd_set 0
    20. STAT get_hits 0
    21. STAT get_misses 0
    22. STAT evictions 0
    23. STAT bytes_read 9
    24. STAT bytes_written 14
    25. STAT limit_maxbytes 67108864
    26. STAT threads 4
    27. END

    3、stats malloc 显示内存分配数据

    1. stats malloc
    2. STAT arena_size 708608
    3. STAT free_chunks 4
    4. STAT fastbin_blocks 0
    5. STAT mmapped_regions 65
    6. STAT mmapped_space 66752512
    7. STAT max_total_alloc 0
    8. STAT fastbin_space 0
    9. STAT total_alloc 614032
    10. STAT total_free 94576
    11. STAT releasable_space 94272
    12. END

    4、stats maps  是把/proc/self/maps的数据显示出来。

    如果远程攻击者连接到了memcached的TCP端口(默认11211)并发布了stats maps命令,Memcached就会直接将/proc/self/maps的输出管道传输给客户端。这可能导致泄漏所分配内存区域的地址。

    1. stats maps
    2. 00365000-00378000 r-xp 00000000 08:01 149004     /lib/libnsl-2.3.4.so
    3. 00378000-00379000 r--p 00012000 08:01 149004     /lib/libnsl-2.3.4.so
    4. 00379000-0037a000 rw-p 00013000 08:01 149004     /lib/libnsl-2.3.4.so
    5. 0037a000-0037c000 rw-p 0037a000 00:00 0
    6. 0070c000-00722000 r-xp 00000000 08:01 147620     /lib/ld-2.3.4.so
    7. 00722000-00723000 r--p 00015000 08:01 147620     /lib/ld-2.3.4.so
    8. 00723000-00724000 rw-p 00016000 08:01 147620     /lib/ld-2.3.4.so
    9. 00726000-0084c000 r-xp 00000000 08:01 147621     /lib/tls/libc-2.3.4.so
    10. 0084c000-0084e000 r--p 00125000 08:01 147621     /lib/tls/libc-2.3.4.so
    11. 0084e000-00850000 rw-p 00127000 08:01 147621     /lib/tls/libc-2.3.4.so
    12. 00850000-00852000 rw-p 00850000 00:00 0
    13. 00891000-0089f000 r-xp 00000000 08:01 147624     /lib/tls/libpthread-2.3.4.so
    14. 0089f000-008a0000 r--p 0000d000 08:01 147624     /lib/tls/libpthread-2.3.4.so
    15. 008a0000-008a1000 rw-p 0000e000 08:01 147624     /lib/tls/libpthread-2.3.4.so
    16. 008a1000-008a3000 rw-p 008a1000 00:00 0
    17. 008a5000-008b4000 r-xp 00000000 08:01 147628     /lib/libresolv-2.3.4.so
    18. 008b4000-008b5000 r--p 0000f000 08:01 147628     /lib/libresolv-2.3.4.so
    19. 008b5000-008b6000 rw-p 00010000 08:01 147628     /lib/libresolv-2.3.4.so
    20. 008b6000-008b8000 rw-p 008b6000 00:00 0
    21. 009c7000-009cf000 r-xp 00000000 08:01 149005     /lib/tls/librt-2.3.4.so
    22. 009cf000-009d0000 r--p 00007000 08:01 149005     /lib/tls/librt-2.3.4.so
    23. 009d0000-009d1000 rw-p 00008000 08:01 149005     /lib/tls/librt-2.3.4.so
    24. 009d1000-009db000 rw-p 009d1000 00:00 0
    25. 00d28000-00d3b000 r-xp 00000000 08:02 688822     /usr/local/sinawap/lib/libevent-1.4.so.2.0.0
    26. 00d3b000-00d3c000 rw-p 00013000 08:02 688822     /usr/local/sinawap/lib/libevent-1.4.so.2.0.0
    27. 00d3c000-00d3d000 rw-p 00d3c000 00:00 0
    28. 08048000-08052000 r-xp 00000000 08:02 905179     /usr/local/sinawap/bin/memcached
    29. 08052000-08053000 rw-p 0000a000 08:02 905179     /usr/local/sinawap/bin/memcached
    30. 08053000-08056000 rw-p 08053000 00:00 0
    31. 08499000-084ba000 rw-p 08499000 00:00 0
    32. b7f64000-b7fa8000 rw-p b7f64000 00:00 0
    33. bff9f000-c0000000 rw-p bff9f000 00:00 0
    34. ffffe000-fffff000 r-xp 00000000 00:00 0
    35.  

    5、stats size

    6、stats slabs

    详细介绍stats slabs

    1. STAT 1:chunk_size 88
    2. STAT 1:chunks_per_page 11915
    3. STAT 1:total_pages 1
    4. STAT 1:total_chunks 11915
    5. STAT 1:used_chunks 11915
    6. STAT 1:free_chunks 0
    7. STAT 1:free_chunks_end 11914
    8. STAT active_slabs 1
    9. STAT total_malloced 1048520
    10. END

    chunk_size:每个chunk(块)使用的空间数量,一个item存储到一个近似大小的chunk中

    chunk_per_page:每page存在的chunk数量,slabs是按页(page)分配的,一页一般为1M,每个slab(也即每页)又划分为若干chunk,这里涉及到memcached的内存管理,这里不多解释,可以参考后面的附文。

    total_pages:该slabclass分配到的page数量

    total_chunks:该slabclass拥有的chunk数量

    used_chunks:已经分配给item的chunk数量(不一定已经装填了item)

    free_chunks:尚未分配给item的chunk数量,或者由delete释放的chunk

    free_chunks_end:slabclass中最后一页的自由块数量,即该slabclass尚有多少自由块可以用来装填item

    active_slabs:已分配的slabclass数量

    total_malloced:已分配给slab page的内存数量

    7、stats items 显示各个slab中item的数目和最老item的年龄(最后一次访问距离现在的秒数)stats detail [on|off|dump]

    设置或者显示详细操作记录

    参数为on,打开详细操作记录

    参数为off,关闭详细操作记录

    参数为dump,显示详细操作记录(每一个键值get、set、hit、del的次数)

    1. stats items dump
    2. STAT items:1:number 7
    3. STAT items:1:age 23124
    4. STAT items:1:evicted 0
    5. STAT items:1:outofmemory 0
    6. .........
    7. END

    8、stats cachedump slab_id limit_num   显示某个slab中的前limit_num个key列表

    显示格式如下:ITEM key_name [ value_length b; expire_time|access_time s]其中,memcached 1.2.2及以前版本显示的是  访问时间(timestamp) 1.2.4以上版本,包括1.2.4显示 过期时间(timestamp)

    如果是永不过期的key,expire_time会显示为服务器启动的时间

    1. stats cachedump 7 2
    2. ITEM copy_test1 [250 b; 1207795754 s]
    3. ITEM copy_test [248 b; 1207793649 s]stats slabs

    显示各个slab的信息,包括chunk的大小、数目、使用情况等

    9、stats detail dump  ( stats detail  [on|off|dump]  )

      1. PREFIX copy_test2 get 1 hit 1 set 0 del 0
      2. PREFIX copy_test1 get 1 hit 1 set 0 del 0
      3. PREFIX cpy get 1 hit 0 set 0 del 0
  • 相关阅读:
    SQL server分离和附加数据库
    sql-server的添加数据库文件(日志数据)以及收缩数据库文件(日志数据)
    sql语句中的join用法(可视化解释)
    SQL语句(floor、ceiling和round以及left和right)
    怎样重新获得别人的信任-知识就是力量(思维导图)
    怎样让孩子爱上学习-知识就是力量(思维导图)
    洛谷-P1036 选数
    洛谷-P1028 数的计算
    洛谷-P1914 小书童——密码
    洛谷-P1598 垂直柱状图
  • 原文地址:https://www.cnblogs.com/newcapecjmc/p/11550142.html
Copyright © 2020-2023  润新知