searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

PHP扩展比对:memcache vs memcached

2023-05-24 00:46:47
88
0
收集现有博文里都集中在描述memcache扩展的缺陷,简单总结如下:
  1. 高并发下TS不好,不稳定
  2. 协议支持不完整: memcached扩展基于memcached项目的lib库,能够以极低的成本跟进memcache的更新;并且因为此特点,也支持了更多的mc协议。
  3. 将数字存储为字符串: 对于强类型,或者是php中"==="这种比较会造成困扰,如set一个test:1, get test会返回"1",与1去做"==="会返回false,造成开发者困惑;
memcached扩展(比对memcache extension)功能上的优化点:
  1. 提供了setOption api 可以统一设置flag
  2. 支持二进制协议,提供了更高的性能,低内存、线程安全
  3. 功能更多:cas 检查并设置
memcache扩展(比对memcached extension)更多的功能点(09年的2.2.0开始支持一致性hash):
  1. 支持OO和过程两组接口,而memcached扩展只支持OO
  2. 支持获取or设置key时的failover
其中功能点1不够吸引人,PHP5版本之后,全线切OO编程,因此OO方法足够实现用户的直接使用,关键是功能点2。查阅资料可以得知,当网络抖动or部分服务临时不可用时,memcache扩展会主动的进行rehash,造成数据一致性问题,以一个简单的计数器(限流用)举例:
<?php                                                                                                                                                                     		error_reporting(-1);
	//$client = new memcached;
	$client = new memcache;
	$arr = array(
	    array("host"=>"127.0.0.1","port"=>11211),
	    array("host"=>"127.0.0.1","port"=>11212),
	);
	foreach ($arr as $ele)
	{
	    $client->addServer($ele["host"],$ele["port"],true);
	}
	$counter = $client->get('counter');
	var_dump($counter);
	if (empty($counter))
	    $client->set('counter', 100, 0);
	for ($i=0; $i < 100; $i++)
	{
	    try
	    {
	        printf("get counter...");
	        sleep(2);
	        $counter = $client->get('counter');
	        printf($counter);
	        if (false === $counter)
	        {
	            printf("connect error");
	            sleep(1);
	            continue;
	        }
	        if (0 >= $counter)
	        {
	            printf("loop end\n");
	            sleep(1);
	            exit(1);
	        }
	        printf("set counter...\n");
	        sleep(2);
	        $client->set('counter', $counter - 1);
	    }
	    catch (Exception $e)
	    {
	        echo "*";
	        var_dump($e->getMessage());
	        continue;
	    }
	}
	exit(0);
 
模拟错误场景:
a. php连接11211和11212集群,counter作为key存在11211实例上;
b. 循环继续,eg:当计数器到90的循环内,在set counter阶段,mcd进程11211失效(以kill来仿真),则将会把counter作为key写入11212节点中(报一个notice) ;
c. 计数器继续递减,eg:当counter为80时,在get counter阶段 11211又启动,所以从11211中拿数据,此时数据为false;在set counter阶段,则将counter=>80写到11211中;
d. 计数器继续递减,eg:当counter为70时,在get counter阶段 11211又失效,则获取counter会拿到上一次切换的点80;
e. 如果使用memcached扩展,则一旦对应的节点失效就会报错,保证通知到运维方,对mc集群进行处理。
由于集群的网络环境不可控,单次操作超时 or 单节点短时间不可用的场景会频繁出现,因此不会使用随机节点rehash的方式来保证系统可用,对数据一致性造成的负面影响过大,因此在memcached扩展中,选择直接返回false,是取舍上收益更大的选择。
 
针对此错误场景的通用解法应该是:
1. 本地缓存(临时方案)
2. 利用缓存代理(magent)
 
总结memcache扩展与memcached扩展对比如下表:
 
 
PECL/MEMCACHE
PECL/MEMCACHED
FIRST RELEASE DATE
2004-06-08
2009-01-29 (beta)
ACTIVELY DEVELOPED
Yes
Yes
EXTERNAL DEPENDENCY
None
libmemcached
Features
 
 
AUTOMATIC KEY FIXUP
Yes
No
APPEND/PREPEND
No
Yes
AUTOMATIC SERIALZATION
Yes
Yes
BINARY PROTOCOL
No
Optional
CAS
No
Yes
COMPRESSION
Yes
Yes
COMMUNICATION TIMEOUT
Connect Only
Various Options
CONSISTENT HASHING
Yes
Yes
DELAYED GET
No
Yes
MULTI-GET
Yes
Yes
SESSION SUPPORT
Yes
Yes
SET/GET TO A SPECIFIC SERVER
No
Yes
STORES NUMERICS
Converted to Strings
Yes
 
因此从一个中间件扩展的简单选型可以发现:在做开发框架技术选型时,设计者要保证对中间件扩展的掌握并进行充分测试。根据具体业务场景,进行合理选型。
0条评论
0 / 1000
范****平
4文章数
0粉丝数
范****平
4 文章 | 0 粉丝
原创

PHP扩展比对:memcache vs memcached

2023-05-24 00:46:47
88
0
收集现有博文里都集中在描述memcache扩展的缺陷,简单总结如下:
  1. 高并发下TS不好,不稳定
  2. 协议支持不完整: memcached扩展基于memcached项目的lib库,能够以极低的成本跟进memcache的更新;并且因为此特点,也支持了更多的mc协议。
  3. 将数字存储为字符串: 对于强类型,或者是php中"==="这种比较会造成困扰,如set一个test:1, get test会返回"1",与1去做"==="会返回false,造成开发者困惑;
memcached扩展(比对memcache extension)功能上的优化点:
  1. 提供了setOption api 可以统一设置flag
  2. 支持二进制协议,提供了更高的性能,低内存、线程安全
  3. 功能更多:cas 检查并设置
memcache扩展(比对memcached extension)更多的功能点(09年的2.2.0开始支持一致性hash):
  1. 支持OO和过程两组接口,而memcached扩展只支持OO
  2. 支持获取or设置key时的failover
其中功能点1不够吸引人,PHP5版本之后,全线切OO编程,因此OO方法足够实现用户的直接使用,关键是功能点2。查阅资料可以得知,当网络抖动or部分服务临时不可用时,memcache扩展会主动的进行rehash,造成数据一致性问题,以一个简单的计数器(限流用)举例:
<?php                                                                                                                                                                     		error_reporting(-1);
	//$client = new memcached;
	$client = new memcache;
	$arr = array(
	    array("host"=>"127.0.0.1","port"=>11211),
	    array("host"=>"127.0.0.1","port"=>11212),
	);
	foreach ($arr as $ele)
	{
	    $client->addServer($ele["host"],$ele["port"],true);
	}
	$counter = $client->get('counter');
	var_dump($counter);
	if (empty($counter))
	    $client->set('counter', 100, 0);
	for ($i=0; $i < 100; $i++)
	{
	    try
	    {
	        printf("get counter...");
	        sleep(2);
	        $counter = $client->get('counter');
	        printf($counter);
	        if (false === $counter)
	        {
	            printf("connect error");
	            sleep(1);
	            continue;
	        }
	        if (0 >= $counter)
	        {
	            printf("loop end\n");
	            sleep(1);
	            exit(1);
	        }
	        printf("set counter...\n");
	        sleep(2);
	        $client->set('counter', $counter - 1);
	    }
	    catch (Exception $e)
	    {
	        echo "*";
	        var_dump($e->getMessage());
	        continue;
	    }
	}
	exit(0);
 
模拟错误场景:
a. php连接11211和11212集群,counter作为key存在11211实例上;
b. 循环继续,eg:当计数器到90的循环内,在set counter阶段,mcd进程11211失效(以kill来仿真),则将会把counter作为key写入11212节点中(报一个notice) ;
c. 计数器继续递减,eg:当counter为80时,在get counter阶段 11211又启动,所以从11211中拿数据,此时数据为false;在set counter阶段,则将counter=>80写到11211中;
d. 计数器继续递减,eg:当counter为70时,在get counter阶段 11211又失效,则获取counter会拿到上一次切换的点80;
e. 如果使用memcached扩展,则一旦对应的节点失效就会报错,保证通知到运维方,对mc集群进行处理。
由于集群的网络环境不可控,单次操作超时 or 单节点短时间不可用的场景会频繁出现,因此不会使用随机节点rehash的方式来保证系统可用,对数据一致性造成的负面影响过大,因此在memcached扩展中,选择直接返回false,是取舍上收益更大的选择。
 
针对此错误场景的通用解法应该是:
1. 本地缓存(临时方案)
2. 利用缓存代理(magent)
 
总结memcache扩展与memcached扩展对比如下表:
 
 
PECL/MEMCACHE
PECL/MEMCACHED
FIRST RELEASE DATE
2004-06-08
2009-01-29 (beta)
ACTIVELY DEVELOPED
Yes
Yes
EXTERNAL DEPENDENCY
None
libmemcached
Features
 
 
AUTOMATIC KEY FIXUP
Yes
No
APPEND/PREPEND
No
Yes
AUTOMATIC SERIALZATION
Yes
Yes
BINARY PROTOCOL
No
Optional
CAS
No
Yes
COMPRESSION
Yes
Yes
COMMUNICATION TIMEOUT
Connect Only
Various Options
CONSISTENT HASHING
Yes
Yes
DELAYED GET
No
Yes
MULTI-GET
Yes
Yes
SESSION SUPPORT
Yes
Yes
SET/GET TO A SPECIFIC SERVER
No
Yes
STORES NUMERICS
Converted to Strings
Yes
 
因此从一个中间件扩展的简单选型可以发现:在做开发框架技术选型时,设计者要保证对中间件扩展的掌握并进行充分测试。根据具体业务场景,进行合理选型。
文章来自个人专栏
开发实录
4 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0