探讨 - 缓存存储方案:mysql vs memcached

2014-01-06 20:16:12 +08:00
 Tianpu
key使用md5特征字符串

方案一:
使用mysql:

CREATE TABLE IF NOT EXISTS `keys` (
`key` varchar(32) NOT NULL,
`time` int(12) NOT NULL,
UNIQUE KEY `key` (`key`),
KEY `time` (`time`)
) ENGINE=MyISAM;

CREATE TABLE IF NOT EXISTS `tmp0` (
`key` varchar(32) NOT NULL,
`value` blob NOT NULL,
`time` int(12) unsigned NOT NULL,
KEY `key` (`key`)
) ENGINE=MyISAM;

.... tmp1 -> tmpf;

一共17个表

逻辑上这么处理

key的首字符用来分表到 tmp0 -> tmpf

添加数据:添加key和有效时间到keys表;添加key value 有效时间到tmp0-f的数据表
读取数据:根据key直接从tmp*读取数据 做下有效时间判断 过期则删除缓存
过期处理:使用计划任务从keys表读取过期数据索引 批量删除


方案二:

使用memcached

添加数据:添加key value 过期时间到memcached
读取数据:根据key从memcached直接读取数据
过期处理:memcached自动维护


我想问的是方案一有什么明显的缺陷吗? 跟方案二相比 系统瓶颈在哪里?

如果1000万数据缓存的话 单挑数据压缩后3K 方案一索引大小是32*10000000/16=20M 也不会卡的 方案二如果有优势在哪里?

我想到的可能是内存读取速度比硬盘快 那如果SSD做RAID10 使用内存的memcached还有优势吗?

实际测试中 方案一速度是0.0008 方案二是0.0004

不考虑非常海量的并发
4800 次点击
所在节点    程序员
24 条回复
Ever
2014-01-06 20:41:17 +08:00
方案一表类型改成innodb, innodb文件格式设置成barracuda.

把表简化成一个, 不用分区或者分表
key binary(16) primary_key
time int index
value blob


还可以直接通过handlersocket读取数据, 而不是sql.

以上, 一家之言.
Actrace
2014-01-06 21:08:43 +08:00
1,SSD速度永远赶不上内存...
2,你若是用MYISAM,那么你的业务基本没有写入和更新咯?MYISAM锁表是很蛋疼的.
jimrok
2014-01-06 21:31:04 +08:00
不明白是做什么用的?
Maslino
2014-01-06 21:34:55 +08:00
我想问问楼主实际是如何做性能测试的?缓存的是什么样的数据,单条压缩后仍然有3KB?
mahone3297
2014-01-06 21:36:55 +08:00
@Ever innodb文件格式设置成barracuda 这句话没看懂。。
Tianpu
2014-01-06 22:10:39 +08:00
@Maslino ab测试不能说明问题 又没有别的测试 我就贴下吧

**********************************************************************

128并发:

方案一:
Write errors: 0
Total transferred: 200530818 bytes
HTML transferred: 198350958 bytes
Requests per second: 822.91 [#/sec] (mean)
Time per request: 155.545 [ms] (mean)
Time per request: 1.215 [ms] (mean, across all concurrent requests)
Transfer rate: 15737.46 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 13 22.8 1 133
Processing: 10 142 53.2 142 676
Waiting: 0 131 57.5 137 676
Total: 11 155 51.1 147 705

Percentage of the requests served within a certain time (ms)
50% 147
66% 161
75% 173
80% 181
90% 209
95% 237
98% 279
99% 318
100% 705 (longest request)


方案二:
Write errors: 0
Total transferred: 200939520 bytes
HTML transferred: 198758400 bytes
Requests per second: 819.24 [#/sec] (mean)
Time per request: 156.241 [ms] (mean)
Time per request: 1.221 [ms] (mean, across all concurrent requests)
Transfer rate: 15699.26 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 21 27.1 6 137
Processing: 9 135 51.5 129 445
Waiting: 1 118 56.1 112 434
Total: 12 156 51.9 149 445

Percentage of the requests served within a certain time (ms)
50% 149
66% 169
75% 187
80% 195
90% 223
95% 248
98% 279
99% 308
100% 445 (longest request)

*********************************************************************


1024并发:

方案一:
Write errors: 0
Total transferred: 200336198 bytes
HTML transferred: 198156938 bytes
Requests per second: 801.65 [#/sec] (mean)
Time per request: 1277.367 [ms] (mean)
Time per request: 1.247 [ms] (mean, across all concurrent requests)
Transfer rate: 15315.95 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 51 98.1 1 623
Processing: 32 1191 540.9 1237 3749
Waiting: 7 1090 471.4 1221 3474
Total: 96 1241 518.5 1251 4039

Percentage of the requests served within a certain time (ms)
50% 1251
66% 1315
75% 1355
80% 1519
90% 1848
95% 2017
98% 2366
99% 3112
100% 4039 (longest request)


方案二:

Total transferred: 200939520 bytes
HTML transferred: 198758400 bytes
Requests per second: 824.39 [#/sec] (mean)
Time per request: 1242.128 [ms] (mean)
Time per request: 1.213 [ms] (mean, across all concurrent requests)
Transfer rate: 15797.89 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 70 113.6 12 597
Processing: 14 1131 484.6 1066 2970
Waiting: 9 1011 461.8 992 2431
Total: 47 1201 452.1 1176 2970

Percentage of the requests served within a certain time (ms)
50% 1176
66% 1279
75% 1426
80% 1532
90% 1800
95% 1959
98% 2328
99% 2657
100% 2970 (longest request)


************************************************************************

高并发mysql的确不如memcached 一般并发 mysql劣势不是很明显

一般情况下,只读是这样子的:

方案一:

73dc7f908ca127684c9cb874dbc3392d
73dc7f908ca127684c9cb874dbc3392d
73dc7f908ca127684c9cb874dbc3392d
73dc7f908ca127684c9cb874dbc3392d
73dc7f908ca127684c9cb874dbc3392d
73dc7f908ca127684c9cb874dbc3392d
73dc7f908ca127684c9cb874dbc3392d
73dc7f908ca127684c9cb874dbc3392d
73dc7f908ca127684c9cb874dbc3392d

load in 0.000408888s

方案二:

23618634799318c968a5a35c8cac0974
23618634799318c968a5a35c8cac0974
23618634799318c968a5a35c8cac0974
23618634799318c968a5a35c8cac0974
23618634799318c968a5a35c8cac0974
23618634799318c968a5a35c8cac0974
23618634799318c968a5a35c8cac0974
23618634799318c968a5a35c8cac0974
23618634799318c968a5a35c8cac0974

load in 0.000947952s
9hills
2014-01-06 22:11:16 +08:00
simple is better,你的方案1也太过度设计了吧
Tianpu
2014-01-06 22:12:46 +08:00
结论似乎是mysql并发不行 貌似就是一般结论了 好处是mysql相对更加持久和不怕重启 哎 我还是改回memcached吧

多些楼上各位 都送钱了
Tianpu
2014-01-06 22:13:54 +08:00
@9hills 清理缓存方便些 被动过期数据没有触发就麻烦些 多存一份数据 删除过期数据更可控
9hills
2014-01-06 22:17:19 +08:00
@Tianpu 持久化看看redis吧
Tianpu
2014-01-06 22:18:05 +08:00
@9hills 不喜欢名字 :)
jimrok
2014-01-07 00:23:31 +08:00
为什么不测试redis呢?
kindy
2014-01-07 00:26:47 +08:00
@Tianpu redis 多好的名字呀
bakac
2014-01-07 09:10:33 +08:00
mysql 有内存存储引擎的 如果不需要持久化 可以用这个 如果需要持久化 就还是 innodb
est
2014-01-07 09:25:44 +08:00
@bakac 那个玩意写入数据要锁表。
bakac
2014-01-07 09:42:47 +08:00
@est 忘记了( 我只记得他能很快....
likuku
2014-01-07 09:59:41 +08:00
memcached 有个日本人作的版本,支持两台memcached双向自动同步,假若一台坏掉,之后恢复运作会自动从活着的那台抓回数据复活。
Tianpu
2014-01-07 10:43:55 +08:00
@bakac 应该不是查询速度的问题 查询速度无论哪种都非常快

就是高并发下mysql不如memcached
likuku
2014-01-07 12:10:28 +08:00
@Tianpu 没考虑过单一web服务器/web前端? 这部分也会造成瓶颈吧。

只单纯测试 mysql 和 memcached 的话,直接用同一种语言的API来测或许会更公平。
Maslino
2014-01-07 13:05:31 +08:00
@est Innodb引擎的锁机制不一样哦

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/95901

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX