常量,使得每一个slab大小正好等于chunk长度的整数倍,这样一个 slab就可以正好划分成n个chunk。这个数值应该比较接近1MB,过大的话同样会造成冗余,过小的话会造成次数过多的alloc,根据chunk长 度为200,选择1000000作为POWER_BLOCK的值,这样一个slab就是100万字节,不是1048576。三个冗余问题都解决了,空间利 用率会大大提升。 351. 修改 slabs_clsid 函数,让它直接返回一个定值(比如 1 ): 352.
353. unsigned int slabs_clsid(size_t size) { 354. return 1; 355. }
356. 修改slabs_init函数,去掉循环创建所有classid属性的部分,直接添加slabclass[1]:
357. slabclass[1].size = 200; //每chunk200字节 358. slabclass[1].perslab = 5000; //1000000/200 359. ◎Memcached客户端
360. Memcached是一个服务程序,使用的时候可以根据它的协议,连接到memcached服务器上,发送命令给服务进程,就可以操作上面 的数据。为了方便使用,memcached有很多个客户端程序可以使用,对应于各种语言,有各种语言的客户端。基于C语言的有libmemcache、 APR_Memcache;基于Perl的有Cache::Memcached;另外还有Python、Ruby、Java、C#等语言的支持。PHP的 客户端是最多的,不光有mcache和PECL memcache两个扩展,还有大把的由PHP编写的封装类,下面介绍一下在PHP中使用memcached的方法:
361. mcache扩展是基于libmemcache再封装的。libmemcache一直没有发布stable版本,目前版本是1.4.0- rc2,可以在这里找到。libmemcache有一个很不好的特性,就是会向stderr写很多错误信息,一般的,作为lib使用的时候,stderr 一般都会被定向到其它地方,比如Apache的错误日志,而且libmemcache会自杀,可能会导致异常,不过它的性能还是很好的。
362. mcache扩展最后更新到1.2.0-beta10,作者大概是离职了,不光停止更新,连网站也打不开了(~_~),只能到其它地方去获 取这个不负责的扩展了。解压后安装方法如常:phpize & configure & make & make install,一定要先安装libmemcache。使用这个扩展很简单: 363. 364.
365. $mc = memcache(); // 创建一个memcache连接对象,注意这里不是用new!
366. $mc->add_server('localhost', 11211); // 添加一个服务进程 367. $mc->add_server('localhost', 11212); // 添加第二个服务进程 368. $mc->set('key1', 'Hello'); // 写入key1 => Hello
369. $mc->set('key2', 'World', 10); // 写入key2 => World,10秒过期
370. $mc->set('arr1', array('Hello', 'World')); // 写入一个数组 371. $key1 = $mc->get('key1'); // 获取'key1'的值,赋给$key1
372. $key2 = $mc->get('key2'); // 获取'key2'的值,赋给$key2,如果超过10秒,就取不到了
373. $arr1 = $mc->get('arr1'); // 获取'arr1'数组 374. $mc->delete('arr1'); // 删除'arr1' 375. $mc->flush_all(); // 删掉所有数据
376. $stats = $mc->stats(); // 获取服务器信息 377. var_dump($stats); // 服务器信息是一个数组 378. ?>
379. 这个扩展的好处是可以很方便地实现分布式存储和负载均衡,因为它可以添加多个服务地址,数据在保存的时候是会根据hash结果定位到某台服务器上 的,这也是libmemcache的特性。libmemcache支持集中hash方式,包括CRC32、ELF和Perl hash。
380. PECL memcache是PECL发布的扩展,目前最新版本是2.1.0,可以在pecl网站得到。memcache扩展的使用方法可以在新一些的PHP手册中找到,它和mcache很像,真的很像: 381. 382.
384. $memcache = new Memcache;
385. $memcache->connect('localhost', 11211) or die (\connect\386.
387. $version = $memcache->getVersion(); 388. echo \389.
390. $tmp_object = new stdClass; 391. $tmp_object->str_attr = 'test'; 392. $tmp_object->int_attr = 123; 393.
394. $memcache->set('key', $tmp_object, false, 10) or die (\to save data at the server\
395. echo \data in the cache (data will expire in 10 seconds)n\396.
397. $get_result = $memcache->get('key'); 398. echo \399.
400. var_dump($get_result); 401. 402. ?>
403. 这个扩展是使用php的stream直接连接memcached服务器并通过socket发送命令的。它不像libmemcache那样完善,也不 支持add_server这种分布操作,但是因为它不依赖其它的外界程序,兼容性要好一些,也比较稳定。至于效率,差别不是很大。
404. 另外,有很多的PHP class可以使用,比如MemcacheClient.inc.php,phpclasses.org上可以找到很多,一般都是对perl client API的再封装,使用方式很像。 405.
406. ◎BSM_Memcache
407. 从C client来说,APR_Memcache是一个很成熟很稳定的client程序,支持线程锁和原子级操作,保证运行的稳定性。不过它是基于APR的 (APR将在最后一节介绍),没有libmemcache的应用范围广,目前也没有很多基于它开发的程序,现有的多是一些Apache Module,因为它不能脱离APR环境运行。但是APR倒是可以脱离Apache单独安装的,在APR网站上可以下载APR和APR-util,不需要 有Apache,可以直接安装,而且它是跨平台的。
408. BSM_Memcache是我在BS.Magic项目中开发的一个基于
APR_Memcache的PHP扩展,说起来有点拗口,至少它把APR扯进了PHP扩展中。这个程序很简单,也没做太多的功能,只是一种形式的尝试,它支持服务器分组。
409. 和mcache扩展支持多服务器分布存储不同,BSM_Memcache支持多组服务器,每一组内的服务器还是按照hash方式来分布保存 数据,但是两个组中保存的数据是一样的,也就是实现了热备,它不会因为一台服务器发生单点故障导致数据无法获取,除非所有的服务器组都损坏(例如机房停 电)。当然实现这个功能的代价就是性能上的牺牲,在每次添加删除数据的时候都要扫描所有的组,在get数据的时候会随机选择一组服务器开始轮询,一直到找 到数据为止,正常情况下一次就可以获取得到。 410. BSM_Memcache只支持这几个函数: 411.
412. zend_function_entry bsm_memcache_functions[] = 413. {
414. PHP_FE(mc_get, NULL) 415. PHP_FE(mc_set, NULL) 416. PHP_FE(mc_del, NULL) 417. PHP_FE(mc_add_group, NULL) 418. PHP_FE(mc_add_server, NULL) 419. PHP_FE(mc_shutdown, NULL) 420. {NULL, NULL, NULL} 421. };
422. mc_add_group函数返回一个整形(其实应该是一个object,我偷懒了~_~)作为组ID,mc_add_server的时候要提供两个参数,一个是组ID,一个是服务器地址(ADDR : PORT)。 423. 424. /**
425. * Add a server group 426. */
427. PHP_FUNCTION(mc_add_group) 428. {
429. apr_int32_t group_id; 430. apr_status_t rv; 431.
432. if (0 != ZEND_NUM_ARGS()) 433. {
434. WRONG_PARAM_COUNT; 435. RETURN_NULL(); 436. } 437.
438. group_id = free_group_id(); 439. if (-1 == group_id) 440. {
441. RETURN_FALSE; 442. } 443.
444. apr_memcache_t *mc;
445. rv = apr_memcache_create(p, MAX_G_SERVER, 0, &mc); 446.
447. add_group(group_id, mc); 448.
449. RETURN_DOUBLE(group_id); 450. } 451. /**
452. * Add a server into group 453. */
454. PHP_FUNCTION(mc_add_server) 455. {
456. apr_status_t rv;
457. apr_int32_t group_id; 458. double g;
459. char *srv_str; 460. int srv_str_l; 461.
462. if (2 != ZEND_NUM_ARGS()) 463. {
464. WRONG_PARAM_COUNT; 465. } 466.
467. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, \&g, &srv_str, &srv_str_l) == FAILURE) 468. {
469. RETURN_FALSE; 470. } 471.
472. group_id = (apr_int32_t) g; 473.
474. if (-1 == is_validate_group(group_id)) 475. {
476. RETURN_FALSE; 477. } 478.
479. char *host, *scope; 480. apr_port_t port; 481.
482. rv = apr_parse_addr_port(&host, &scope, &port, srv_str, p); 483. if (APR_SUCCESS == rv) 484. {
485. // Create this server object 486. apr_memcache_server_t *st;
487. rv = apr_memcache_server_create(p, host, port, 0, 64, 1024, 600, &st);
488. if (APR_SUCCESS == rv) 489. {
490. if (NULL == mc_groups[group_id]) 491. {
492. RETURN_FALSE; 493. } 494.
495. // Add server
496. rv = apr_memcache_add_server(mc_groups[group_id], st); 497.
498. if (APR_SUCCESS == rv) 499. {
500. RETURN_TRUE; 501. } 502. } 503. } 504.
505. RETURN_FALSE; 506. }
507. 在set和del数据的时候,要循环所有的组: 508. 509. /**
510. * Store item into all groups 511. */
512. PHP_FUNCTION(mc_set) 513. {
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库memcached使用文档(6)在线全文阅读。
相关推荐: