热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

分布式缓存系统Memcached实践

Memcached简介Memcached是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、
Memcached简介

Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。天生支持集群
目前有多种平台的Memcached版本,比如Linux、FreeBSD、Solaris 、Mac OS X及Windows平台。
官方网站:http://memcached.org/
我们安装Windows版本来演示。
32bit:下载 memcached-win32-1.4.4-14.zip
64bit:如果需要win64版,下载 memcached-win64-1.4.4-14.zip

Memcached 内存管理机制
Menceched 通过预分配指定的内存空间来存取数据,所有的数据都保存在 memcached 内置的内存中。利用 Slab Allocation 机制来分配和管理内存。按照预先规定的大小,将分配的内存分割成特定长度的内存块,再把尺寸相同的内存块分成组,这些内存块不会释放,可以重复利用。当存入的数据占满内存空间时,Memcached 使用 LRU 算法自动删除不是用的缓存数据,即重用过期数据的内存空间。Memcached 是为缓存系统设计的,因此没有考虑数据的容灾问题,和机器的内存一样,重启机器将会丢失,如果希望服务重启数据依然能保留,那么就需要 sina 网开发的 Memcachedb 持久性内存缓冲系统,当然还有常见的 NOSQL 服务如 redis。默认监听端口:11211

Memcached数据访问模型
  • 添加新的键值对数据

    《分布式缓存系统Memcached实践》
    从图中可以看出,Memcached虽然称为“分布式”缓存服务器,但服务器端并没有“分布式”功能,而是完全由客户端程序库实现的。服务端之间没有任何联系,数据存取都是通过客户端的算法实现的。当客户端要存取数据时,首先会通过算法查找自己维护的服务器哈希列表,找到对应的服务器后,再将数据存往指定服务器。例如:上图中应用程序要新增一个<&#8216;tokyo&#8217;,data>的键值对,它同过set操作提交给Memcached客户端,客户端通过一定的哈希算法(比如:一般的求余函数或者强大的一致性Hash算法)从服务器列表中计算出一个要存储的服务器地址,最后将该键值对存储到计算出来的服务器里边。

  • 获取已存在的键值对数据

    《分布式缓存系统Memcached实践》
    上图中应用程序想要获取Key为‘tokyo’的Value,于是它向Memcached客户端提交了一个Get请求,Memcached客户端还是通过算法从服务器列表查询哪台服务器存有Key为‘tokyo’的Value(即选择刚刚Set到了哪台服务器),如果查到,则向查到的服务器请求返回Key为‘tokyo’的数据。

Memcached分布式的核心—一致性Hash算法

一致性Hash算法是分布式缓存的核心理论,我也学习得不深入,也只是刚刚了解了一下,后面我有空深入学习一下。
  首先,简单的路由算法(通过使用余数Hash)无法满足业务发展时服务器扩容的需要:缓存命中率下降。例如:当3台服务器扩容至4台时,采用普通的余数Hash算法会导致大约75%(3/4)被缓存了的数据无法正确命中,随着服务器集群规模的增大,这个比例会线性地上升。那么,可以想象,当100台服务器的集群中加入一台服务器,不能命中的概率大概是99%(N/N+1),这个结果显然是无法接受的。那么,能否通过改进路由算法,使得新加入的服务器不影响大部分缓存数据的正确性呢?请看下面的一致性Hash算法。
  一致性Hash算法通过一个叫做一致性Hash环的数据结构实现KEY到缓存服务器的Hash映射,如下图所示:

《分布式缓存系统Memcached实践》

具体算法过程是

  1. 先构造一个长度为0~2^32(2的32次幂)个的整数环(又称:一致性Hash环),根据节点名称的Hash值将缓存服务器节点放置在这个Hash环中,如上图中的node1,node2等;
  2. 根据需要缓存的数据的KEY值计算得到其Hash值,如上图中右半部分的“键”,计算其Hash值后离node2很近;
  3. 在Hash环上顺时针查找距离这个KEY的Hash值最近的缓存服务器节点,完成KEY到服务器的Hash映射查找,如上图中离右边这个键的Hash值最近的顺时针方向的服务器节点是node2,因此这个KEY会到node2中读取数据;
      当缓存服务器集群需要扩容的时候,只需要将新加入的节点名称(如node5)的Hash值放入一致性Hash环中,由于KEY总是顺时针查找距离其最近的节点,因此新加入的节点只影响整个环中的一部分。如下图中所示,添加node5后,只影响右边逆时针方向的三个Key/Value对数据,只占整个Hash环中的一小部分。

《分布式缓存系统Memcached实践》

因此,我们可以与之前的普通余数Hash作对比:采用一致性Hash算法时,当3台服务器扩容到4台时,可以继续命中原有缓存数据的概率为75%,远高于普通余数Hash的25%,而且随着集群规模越大,继续命中原有缓存数据的概率也会随之增大。当100台服务器增加1台时,继续命中的概率是99%。
虽然,仍有小部分数据缓存在服务器中无法被读取到,但是这个比例足够小,通过访问数据库也不会对数据库造成致命的负载压力

Memcached与Redis的对比
  • 没有必要过多的关心性能,因为二者的性能都已经足够高了。由于Redis只使用单核,而Memcached可以使用多核,所以在比较上,平均每一个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起Memcached,还是稍有逊色。说了这么多,结论是,无论你使用哪一个,每秒处理请求的次数都不会成为瓶颈。(比如瓶颈可能会在网卡)
  • 如果要说内存使用效率,使用简单的key-value存储的话,Memcached的内存利用率更高,而如果Redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于Memcached。当然,这和你的应用场景和数据特性有关。
  • 如果你对数据持久化和数据同步有所要求,那么推荐你选择Redis,因为这两个特性Memcached都不具备。即使你只是希望在升级或者重启系统后缓存数据不会丢失,选择Redis也是明智的。

因此,我们可以得出一个结论:在简单的Key/Value应用场景(例如缓存),Memcached拥有更高的读写性能;而在数据持久化和数据同步场景,Redis拥有更加强大的功能和更为丰富的数据类型

需要慎重考虑的部分

  • Memcached单个key-value大小有限,一个value最大只支持1MB,而Redis最大支持512MB
  • Memcached只是个内存缓存,对可靠性无要求;而Redis更倾向于内存数据库,因此对对可靠性方面要求比较高
  • 从本质上讲,Memcached只是一个单一key-value内存Cache;而Redis则是一个数据结构内存数据库,支持五种数据类型,因此Redis除单纯缓存作用外,还可以处理一些简单的逻辑运算,Redis不仅可以缓存,而且还可以作为数据库用
  • 新版本(3.0)的Redis是指集群分布式,也就是说集群本身均衡客户端请求,各个节点可以交流,可拓展行、可维护性更强大。
  • MongoDB不支持事务。
安装和启动
  • install

memcached.exe -d install

  • start

memcached.exe -d start

  • stop

memcached.exe -d stop

  • unInstall

memcached.exe -d uninstall

以上的安装和启动都是在默认环境下进行的,在安装时可设置如下参数:

Memcached默认使用端口是11211
默认最大连接数是1024个
默认最大使用内存是64M
默认每个键值对,值存储空间为1M

-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 显示帮助

OK,命令咱们已经执行完了.怎么才知道Memcached服务已经安装成功并启动了呢?
cmd 命令 services.msc

《分布式缓存系统Memcached实践》

检测Memcached服务是否成功启动:

使用telnet命令连接到登录台:telnet 服务器IP地址 11211(11211是默认的Memcached服务端口号)
打印当前Memcache服务器状态:stats

《分布式缓存系统Memcached实践》 stats.png

可以看到,通过stats命令列出了一系列的Memcached服务状态信息,那么这些信息又代表什么意思呢?我们可以通过下图来知道:

《分布式缓存系统Memcached实践》

先把memcached用起来

下载客户端的4个dll,
ICSharpCode.SharpZipLib.dll,log4net.dll,Memcached.ClientLibrary.dll,Commons.dll
跟着我新建一个简单控制台应用程序

using Memcached.ClientLibrary;
using System;
namespace Tdf.RedisCacheTest
{
class AMemcached
{
public static MemcachedClient cache;
static AMemcached()
{
string[] servers = { "127.0.0.1:11211" };
// 初始化池
SockIOPool pool = SockIOPool.GetInstance();
// 设置服务器列表
pool.SetServers(servers);
// 各服务器之间负载均衡的设置比例
pool.SetWeights(new int[] { 1 });
// 初始化时创建连接数
pool.InitCOnnections= 3;
// 最小连接数
pool.MinCOnnections= 3;
// 最大连接数
pool.MaxCOnnections= 5;
// 连接的最大空闲时间,下面设置为6个小时(单位ms),超过这个设置时间,连接会被释放掉
pool.MaxIdle = 1000 * 60 * 60 * 6;
// socket连接的超时时间,下面设置表示不超时(单位ms),即一直保持链接状态
pool.SocketCOnnectTimeout= 0;
// 通讯的超时时间,下面设置为3秒(单位ms),.Net版本没有实现
pool.SocketTimeout = 1000 * 3;
// 维护线程的间隔激活时间,下面设置为30秒(单位s),设置为0时表示不启用维护线程
pool.MaintenanceSleep = 30;
// 设置SocktIO池的故障标志
pool.Failover = true;
// 是否对TCP/IP通讯使用nalgle算法,.net版本没有实现
pool.Nagle = false;
// socket单次任务的最大时间(单位ms),超过这个时间socket会被强行中端掉,当前任务失败。
pool.MaxBusy = 1000 * 10;
pool.Initialize();
cache = new MemcachedClient();
// 是否启用压缩数据:如果启用了压缩,数据压缩长于门槛的数据将被储存在压缩的形式
cache.EnableCompression = false;
// 压缩设置,超过指定大小的都压缩
cache.CompressiOnThreshold= 1024 * 1024;
}
}
class Program
{
static void Main(string[] args)
{
// 存入key为userName,value为Bobby的一个缓存
AMemcached.cache.Add("userName", "Bobby");
// 读出key为a的缓存值
var s = AMemcached.cache.Get("userName");
// 输出
Console.WriteLine(s);
Console.Read();
}
}
}
细品 .NET Memcached.ClientLibrary

说说memcached分布式缓存的设置与应用

string[] servers = { "127.0.0.1:11211", "192.168.2.100:11211" };
// 初始化池
SockIOPool pool = SockIOPool.GetInstance();
// 设置服务器列表
pool.SetServers(servers);
// 各服务器之间负载均衡的设置比例
pool.SetWeights(new int[] { 1, 10 });

Note:

  • 在172.18.5.66,与192.168.10.121两台机器上装memcached服务端。
  • pool.SetWeights这里的1跟10意思是,负载均衡比例,假如11000条数据,大致数据分布为:172.18.5.66分布1000条数据左右。另外一台为10000条左右。
  • memcached服务端并不具备负载均衡的能力,而是memcachedClient实现的,具体存取数据实现的核心是采用一致性Hash算法,把key-value分布到某一台服务器中里边。

说说memcached的数据压缩机制

// 是否启用压缩数据:如果启用了压缩,数据压缩长于门槛的数据将被储存在压缩的形式
cache.EnableCompression = false;
// 压缩设置,超过指定大小的都压缩
cache.CompressiOnThreshold= 1024 * 1024;

Note:

  • 这个处理是在MemcachedClient对象中,设置这个EnableCompression属性,是否使用压缩的意思,如果启用啦压缩功能 ,则ICSharpCode.SharpZipLib类库会在数据超过预设大小时,进行数据压缩处理。
  • CompressionThreshold这个属性是压缩的阀值,默认是15K,如果超过设定的阀值则使用memcached的通讯协议,存数据时给每个数据项分配一个16为的flag表示,用作记录是否有压缩,如果有压缩则提取数据是进行解压。如果没有超过阀值则不压缩,直接存储。
说说怎么使用客户端多个SocketIO池

using Memcached.ClientLibrary;
using System;
namespace Tdf.RedisCacheTest
{
class AMemcached
{
public MemcachedClient cache;
public AMemcached(string poolName)
{
string[] servers = { "127.0.0.1:11211", "192.168.2.100:11211" };
// 初始化池
SockIOPool pool = SockIOPool.GetInstance();
// 设置服务器列表
pool.SetServers(servers);
// 各服务器之间负载均衡的设置比例
pool.SetWeights(new int[] { 1, 10 });
// 初始化时创建连接数
pool.InitCOnnections= 3;
// 最小连接数
pool.MinCOnnections= 3;
// 最大连接数
pool.MaxCOnnections= 5;
// 连接的最大空闲时间,下面设置为6个小时(单位ms),超过这个设置时间,连接会被释放掉
pool.MaxIdle = 1000 * 60 * 60 * 6;
// socket连接的超时时间,下面设置表示不超时(单位ms),即一直保持链接状态
pool.SocketCOnnectTimeout= 0;
// 通讯的超时时间,下面设置为3秒(单位ms),.Net版本没有实现
pool.SocketTimeout = 1000 * 3;
// 维护线程的间隔激活时间,下面设置为30秒(单位s),设置为0时表示不启用维护线程
pool.MaintenanceSleep = 30;
// 设置SocktIO池的故障标志
pool.Failover = true;
// 是否对TCP/IP通讯使用nalgle算法,.net版本没有实现
pool.Nagle = false;
// socket单次任务的最大时间(单位ms),超过这个时间socket会被强行中端掉,当前任务失败。
pool.MaxBusy = 1000 * 10;
pool.Initialize();
cache = new MemcachedClient();
// 是否启用压缩数据:如果启用了压缩,数据压缩长于门槛的数据将被储存在压缩的形式
cache.EnableCompression = false;
// 压缩设置,超过指定大小的都压缩
cache.CompressiOnThreshold= 1024 * 1024;
}
}
class Program
{
static void Main(string[] args)
{
// 存入key为userName,value为Bobby的一个缓存
new AMemcached("poolName").cache.Add("b", 123);
// AMemcached.cache.Add("userName", "Bobby");
// 读出key为a的缓存值
var s = new AMemcached("poolName").cache.Get("userName");
// 输出
Console.WriteLine(s);
Console.Read();
}
}
}

说说memcached的故障转移处理

// 设置SocktIO池的故障标志
pool.Failover = true;

Note:memcached的鼓掌转移是一套正常节点发生故障变为死节点时的处理机制。

  • 开启故障转移:如果发生socket异常,则该节点被添加到存放死节点属性的_hostDead中,新请求被映射到dead server,检测尝试连接死节点的时间间隔属性_hostDeadDuration(默认设置为100ms),如果没有达到设定的间隔时间则key会被映射到可用的server处理,如果达到了时间间隔,则尝试重新链接,连接成功将此节点从_hostDead中去除,连接失败则间隔时间翻倍存放,下次重新连接时间会被拉长。
  • 不开启故障转移:新的请求都会被映射到dead server上,尝试重新建立socket链接,如果连接失败,返回null或者操作失败。

说说key-value中的key与value

  • key在服务端的长度限制为250个字符,建议使用较短的key但不要重复。
  • value的大小限制为1mb,如果大拉,可以使用压缩,如果还大,那可能拆分到多个key中。
Memcached 客户端使用封装

抽象出来了一个接口:

using System;
namespace Tdf.Memcached
{
public interface IMemcached
{
void Add(string key, object value);
void Add(string key, object value, DateTime expiredDateTime);
void Update(string key, object value);
void Update(string key, object value, DateTime expiredDateTime);
void Set(string key, object value);
void Set(string key, object value, DateTime expiredTime);
void Delete(string key);
object Get(string key);
bool KeyExists(string key);
}
}

MemcacheHelper.cs

using Memcached.ClientLibrary;
using System;
using System.Configuration;
namespace Tdf.Memcached
{
///


/// 基于Memcached.ClientLibrary封装使用Memchached信息
/// 读取缓存存放在服务器
///

public class MemcacheHelper
{
///
/// 字段_instance,存放注册的缓存信息
///

private static MemcacheHelper _instance;
///
/// 缓存客户端
///

private readonly MemcachedClient _client;
///
/// 受保护类型的缓存对象,初始化一个新的缓存对象
///

protected MemcacheHelper()
{
// 读取app.Config中需要缓存的服务器地址信息,可以传递多个地址,使用";"分隔
string[] serverList = ConfigurationManager.AppSettings["readWriteHosts"].Split(new char[] { ';' });

try
{
// 初始化池
var sockIoPool = SockIOPool.GetInstance();
// 设置服务器列表
sockIoPool.SetServers(serverList);
// 各服务器之间负载均衡的设置比例
sockIoPool.SetWeights(new int[] { 1 });
// 初始化时创建连接数
sockIoPool.InitCOnnections= 3;
// 最小连接数
sockIoPool.MinCOnnections= 3;
// 最大连接数
sockIoPool.MaxCOnnections= 5;
// 连接的最大空闲时间,下面设置为6个小时(单位ms),超过这个设置时间,连接会被释放掉
sockIoPool.MaxIdle = 1000 * 60 * 60 * 6;
// socket连接的超时时间,下面设置表示不超时(单位ms),即一直保持链接状态
sockIoPool.SocketCOnnectTimeout= 0;
// 通讯的超时时间,下面设置为3秒(单位ms),.Net版本没有实现
sockIoPool.SocketTimeout = 1000 * 3;
// 维护线程的间隔激活时间,下面设置为30秒(单位s),设置为0时表示不启用维护线程
sockIoPool.MaintenanceSleep = 30;
// 设置SocktIO池的故障标志
sockIoPool.Failover = true;
// 是否对TCP/IP通讯使用nalgle算法,.net版本没有实现
sockIoPool.Nagle = false;
// socket单次任务的最大时间(单位ms),超过这个时间socket会被强行中端掉,当前任务失败。
sockIoPool.MaxBusy = 1000 * 10;
sockIoPool.Initialize();
// 实例化缓存对象
_client = new MemcachedClient();
// 是否启用压缩数据:如果启用了压缩,数据压缩长于门槛的数据将被储存在压缩的形式
_client.EnableCompression = false;
// 压缩设置,超过指定大小的都压缩
_client.CompressiOnThreshold= 1024 * 1024;
}
catch (Exception ex)
{
// 错误信息写入事务日志
throw new Exception(ex.Message);
}
}
///
/// 获取缓存的实例对象,方法调用的时候使用
///

///
public static MemcacheHelper GetInstance()
{
return _instance;
}
///
/// 添加缓存信息(如果存在缓存信息则直接重写设置,否则添加)
/// 使用:MemcacheHelper.GetInstance().Add(key,value)
///

/// 需要缓存的键
/// 需要缓存的值
public void Add(string key, object value)
{
if (_client.KeyExists(key))
{
_client.Set(key, value);
}
_client.Add(key, value);
}
///
/// 添加缓存信息
/// 使用:MemcacheHelper.GetInstance().Add(key,value,Datetime.Now())
///

/// 需要缓存的键
/// 需要缓存的值
/// 设置的缓存的过时时间
public void Add(string key, object value, DateTime expiredDateTime)
{
_client.Add(key, value, expiredDateTime);
}
///
/// 修改缓存的值
/// 使用:MemcacheHelper.GetInstance().Update(key,value)
///

/// 需要修改的键
/// 需要修改的值
public void Update(string key, object value)
{
_client.Replace(key, value);
}
///
/// 修改缓存的值
/// 使用:MemcacheHelper.GetInstance().Update(key,value,Datetime.Now())
///

/// 需要修改的键
/// 需要修改的值
/// 设置的缓存的过时时间
public void Update(string key, object value, DateTime expiredDateTime)
{
_client.Replace(key, value, expiredDateTime);
}
///
/// 设置缓存
/// 使用:MemcacheHelper.GetInstance().Set(key,value)
///

/// 设置缓存的键
/// 设置缓存的值
public void Set(string key, object value)
{
_client.Set(key, value);
}
///
/// 设置缓存,并修改过期时间
/// 使用:MemcacheHelper.GetInstance().Set(key,value,Datetime.Now())
///

/// 设置缓存的键
/// 设置缓存的值
/// 设置缓存过期的时间
public void Set(string key, object value, DateTime expiredTime)
{
_client.Set(key, value, expiredTime);
}
///
/// 删除缓存
/// 使用:MemcacheHelper.GetInstance().Delete(key)
///

/// 需要删除的缓存的键
public void Delete(string key)
{
_client.Delete(key);
}
///
/// 获取缓存的值
/// 使用:MemcacheHelper.GetInstance().Get(key)
///

/// 传递缓存中的键
/// 返回缓存在缓存中的信息
public object Get(string key)
{
return _client.Get(key);
}
///
/// 缓存是否存在
/// 使用:MemcacheHelper.GetInstance().KeyExists(key)
///

/// 传递缓存中的键
/// 如果为true,则表示存在此缓存,否则比表示不存在
public bool KeyExists(string key)
{
return _client.KeyExists(key);
}
///
/// 注册Memcache缓存(在Global.asax的Application_Start方法中注册)
/// 使用:MemcacheHelper.RegisterMemcache();
///

public static void RegisterMemcache()
{
if (_instance == null)
{
_instance = new MemcacheHelper();
}
}
}
}

App.config


















Program.cs

using System;
using Tdf.Memcached;
namespace Tdf.MemcachedTest
{
class Program
{
static void Main(string[] args)
{
// 注册Memcache缓存
MemcacheHelper.RegisterMemcache();
// 添加缓存信息(如果存在缓存信息则直接重写设置,否则添加)
MemcacheHelper.GetInstance().Add("userName", "Bobby");
// 缓存是否存在
var tf = MemcacheHelper.GetInstance().KeyExists("userName");
Console.WriteLine(tf);
// 获取缓存的值
var s = MemcacheHelper.GetInstance().Get("userName");
Console.WriteLine(s);
Console.Read();
}
}
}

到此,我们已经完成了一个最小化的memcached集群读写测试Demo。但是,在实际的开发场景中,远不仅仅是存储一个字符串,更多的是存储一个自定义的类的实例对象。这就需要使用到序列化,下面我们来新加一个类Claim,让其作为可序列化的对象来存储进Memcached中。注意:需要为该类加上[Serializable]的特性

using System;
using Tdf.Memcached;
namespace Tdf.MemcachedTest
{
[Serializable]
public class Claim
{
public int UserId { get; set; }
public string UserName { get; set; }
}
class Program
{
static void Main(string[] args)
{
// 注册Memcache缓存
MemcacheHelper.RegisterMemcache();
// 自定义对象存储
Claim claim = new Claim();
claim.UserId = 694802856;
claim.UserName = "难念的经";
MemcacheHelper.GetInstance().Add("Claim", claim);
Claim newMyObj = MemcacheHelper.GetInstance().Get("Claim") as Claim;
Console.WriteLine("Hello,My UserId is {0} and UserName is {1}", newMyObj.UserId, newMyObj.UserName);
Console.Read();
}
}
}

《分布式缓存系统Memcached实践》


推荐阅读
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 上图是InnoDB存储引擎的结构。1、缓冲池InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。因此可以看作是基于磁盘的数据库系统。在数据库系统中,由于CPU速度 ... [详细]
  • PatchODAX8: ... [详细]
  • 什么是堡垒机?堡垒机是一个主机系统,其自身通常经过了一定的加固,具有较高的安全性,可抵御一定的攻击,其作用主 ... [详细]
  • vc写入mysql数据库无效_VC连接mysql数据库错误:libmysql.lib : fatal error LNK1113: invalid machine 解决方法...
    VC连接MySQL的配置过程在上一篇博文中,不过当你设置好,以为万事大吉的时候,运行却出现这个错误:libmysql.lib:fatalerrorLNK1113:inval ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 关于我们EMQ是一家全球领先的开源物联网基础设施软件供应商,服务新产业周期的IoT&5G、边缘计算与云计算市场,交付全球领先的开源物联网消息服务器和流处理数据 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • 本文介绍了OpenStack的逻辑概念以及其构成简介,包括了软件开源项目、基础设施资源管理平台、三大核心组件等内容。同时还介绍了Horizon(UI模块)等相关信息。 ... [详细]
  • Centos下安装memcached+memcached教程
    本文介绍了在Centos下安装memcached和使用memcached的教程,详细解释了memcached的工作原理,包括缓存数据和对象、减少数据库读取次数、提高网站速度等。同时,还对memcached的快速和高效率进行了解释,与传统的文件型数据库相比,memcached作为一个内存型数据库,具有更高的读取速度。 ... [详细]
  • 解决Sharepoint 2013运行状况分析出现的“一个或多个服务器未响应”问题的方法
    本文介绍了解决Sharepoint 2013运行状况分析中出现的“一个或多个服务器未响应”问题的方法。对于有高要求的客户来说,系统检测问题的存在是不可接受的。文章详细描述了解决该问题的步骤,包括删除服务器、处理分布式缓存留下的记录以及使用代码等方法。同时还提供了相关关键词和错误提示信息,以帮助读者更好地理解和解决该问题。 ... [详细]
  • Sleuth+zipkin链路追踪SpringCloud微服务的解决方案
    在庞大的微服务群中,随着业务扩展,微服务个数增多,系统调用链路复杂化。Sleuth+zipkin是解决SpringCloud微服务定位和追踪的方案。通过TraceId将不同服务调用的日志串联起来,实现请求链路跟踪。通过Feign调用和Request传递TraceId,将整个调用链路的服务日志归组合并,提供定位和追踪的功能。 ... [详细]
  • 2021最新总结网易/腾讯/CVTE/字节面经分享(附答案解析)
    本文分享作者在2021年面试网易、腾讯、CVTE和字节等大型互联网企业的经历和问题,包括稳定性设计、数据库优化、分布式锁的设计等内容。同时提供了大厂最新面试真题笔记,并附带答案解析。 ... [详细]
  • .netFramework4.5框架下运行4.0站点程序的问题
    事件的起因:公司部署好的站点突然发现出了问题,经过一步步的查找(查找问题所在的艰辛只有自己知道),查源代码发现 ... [详细]
  • hackingTeam是如何被黑的
    hackingTeam是如何被黑的 ... [详细]
author-avatar
mobiledu2502858263
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有