首页 > 代码库 > 缓存Memcached以及缓存策略

缓存Memcached以及缓存策略

1.什么是memcached

缓存是一种常驻与内存的内存数据库,内存的读取速度远远快于程序在磁盘读取数据的速度。我们在设计程序的时候常常会考虑使用缓存,将经常访问的数据放到内存上面这样可以提高访问数据的速度,同时可以降低磁盘或数据库的压力。
memcached就是一款可以方便实现缓存的工具软件,memcached的优势在于以下几点:
1.实现分布式缓存(支持热部署),通过hashcode根据缓存服务器ip智能分配将数据缓存到的服务器上。
2.实现最近最少访问的数据优先被移除缓存。
3.快速找到适配的存储空间,避免内存的浪费。
4.使用键值对存储数据,方便读取修改等缓存的管理。
5.socket通信,缓存服务器和应用服务器分离。
等等,memcached还含有很多自身的优势。
使用缓存中我们面临的缓存数据无法同步的问题:比如一台缓存服务器突然崩溃那么这台服务器上面的缓存数据就会全部丢失,而且需要在配置中及时去除这台崩溃的服务器IP,这个需要我们编写更多的代码进行相应的控制。

2.memcached内部机制

memcached为了提高数据的存储速度,在安装启动memcached服务的时候,他会自动将分配给memcached的内存分隔为大小不一致的很多块。每当任意一个大小的需要缓存的数据提交过来的时候memcached将会自动找到符合这个数据大小最适合的内存块,然后把数据放到这个块里面。这种方式不仅可以降低内存的浪费同时可以减少了内存分配的时间了。
如果memcached里面的内存已经被使用完了,还需要向里面添加数据的时候,memcached将会把存入缓存中最长时间没有用的数据清除掉。
每次向缓存中添加数据的时候都会带上该数据的有效时间,如果超过了这个有效时间那么缓存的数据自动失效了。
memcached安装到计算机上是一款服务默认端口11211,我们可以通过socket与他建立通信。建立起通信之后就可以通过执行memcached的指令向缓存里面添加取出或修改或删除缓存数据的工作了。

3.C#如何操作memcached

C#建立memcached连接,首先通过socket建立于11211的通信,建立socketpool,然后通过socket发起远程命令的执行语句,在这里使用socket建立连接就需要设定每一次连接建立的最大时间,如果不设定最大时间,那么在建立某一个连接的时候发生了异常,那么机器就会长时间处于等待知道连接超时异常抛出。
使用了线程池和进行Socket的链接。然后通过Socket进行相应的链接操作。
其实memcached作为一种服务,他可以被不同语言不同平台建立连接并执行命令。

4.memcached内部操作指令和名词解释

所有语言建立连接到memcached服务之后,要管理memcached都执行的是同一套的指令集合。

在Windows系统中我们可以使用telnet命令来查看Memcached的相关运行情况如:
stats  telnet xxx.xxx.xxx.xxx 11211
输入stats命令:在这里屏幕是空白,看不到输入的内容,回车之后可以看到Memcached的运行相关信息。
set key 
get key 
memcached客户机命令
set
Add
replace
get
delete
输入stats命令:在这里屏幕是空白,看不到输入的内容,回车之后可以看到Memcached的运行相关信息。
查看出来的结果名词的意思:

Pid: Memcached服务器中的进程编号 Uptime:Memcached服务器启动之后所经历的时间,单位秒 Time:当前系统时间,单位秒 Version: Memcached的版本号 pointer_size:服务器所在主机操作系统的指针大小,一般为32或64 curr_items:表示当前缓存中存放的所有缓存对象的数量 total_items:表示从memcached服务启动到当前时间,系统存储过的所有对象的数量,包括已经删除的对象 bytes:表示系统存储缓存对象所使用的存储空间,单位为字节 curr_connections:表示当前系统打开的连接数 total_connections:表示从memcached服务启动到当前时间,系统打开过的连接的总数 cmd_get:查询缓存的次数,即使不成功也算一次 cmd_set:保存数据的次数,当然这里只保存成功的次数 get_hits:表示获取数据成功的次数。 get_misses:表示获取数据失败的次数。 evictions:为了给新的数据项目释放空间,从缓存移除的缓存对象的数目。比如超过缓存大小时根据LRU算法移除的对象,以及过期的对象 bytes_read:memcached服务器从网络读取的总的字节数 bytes_written:memcached服务器发送到网络的总的字节数 limit_maxbytes:memcached服务缓存允许使用的最大字节数 threads:被请求的工作线程的总数量 缓存命中率 = get_hits / cmd_get * 100% ;

5.良好的缓存

良好的缓存需要具备以下几点:1.灵活指定不同类型的缓存时间。2.可以通过配置文件或管理站点对缓存的配置和管理。3.灵活做到对不同用户的缓存进行管理。4.缓存服务器应该稳定,并能及时备份缓存数据。5.灵活的对缓存的数据进行管理。这里以我接触过的良好的缓存策略,是将缓存的配置填写到一个xml或则json配置文件里面。比如:
<?xml version=‘1.0‘ encoding=‘utf-8‘?>
 <Root>
     <Item>
          <CacheTime>10000</CacheTime>
          <DataType>B2C</DataType>
          <Enabled>True</Enabled>
     </Item>
     <Item>
          <CacheTime>10000</CacheTime>
          <DataType>PHONE</DataType>
          <Enabled>True</Enabled>
      </Item>
 </Root>
上面的一个配置就能很好的指定摸一个类型的缓存时间配置,然后还能启用或停用某一种类型是否进行缓存。

还可以把这个xml配置更加复杂以满足对不同用户的缓存时间其实也是不一样的。在缓存的开发完成之后,对缓存的管理要做到灵活多样。因为在运维过程中常常需要新增或删除或修改某一些缓存的内容所以做到灵活易管理是非常的重要的。

6.缓存的扩展

缓存的我们已经了解了一些了,那么在平时开发中我们可以那些地方使用缓存呢?首先用户经常读取的数据可以放入到缓存之中。其次用户高频写入的数据也可以通过缓存在又换速度。最后网站的一些静态文件内容也可以放入。用户高频写入数据库的数据放入缓存的方式,如果用户每一次写入数据库都需要与数据库建立连接,并将数据写入到数据库势必降低整个运行效率,那么我们就需要降低与数据库建立连接并写入磁盘的次数,所以可以规定一个缓存内容的大小,如果缓存到得数据达到某一个数量级就一次性的将数据写入到数据库,或则定时将缓存中的数据取出然后一并写入数据库。我觉得以上两种方式可以结合起来使用可以降低程序与数据库建立连接写入磁盘所开销的资源。其他的缓存服务软件有redis。非常出色以下几个方面:

1.Redis中,并不是所有的数据都一直存储在内存中的,这是和Memcached相比一个最大的区别。2.Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储。3.Redis支持数据的备份,即master-slave模式的数据备份。4.Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。我个人认为最本质的不同是Redis在很多方面具备数据库的特征,或者说就是一个数据库系统,而Memcached只是简单的K/V缓存