每个用户请求就会 UPDATE 一下 mysql 数据库。。 如果只有一台服务器,求问各位 V 友至少要什么配置
1
abelyao 2016-11-19 22:08:42 +08:00
4000 请求是同时产生还是会有错开一两秒? update 的 sql 复杂不?单次执行时间是多少? mysql 是也在本地吗?
|
2
prondtoo 2016-11-19 22:15:04 +08:00
刷单么?
|
3
ipconfiger 2016-11-19 22:16:05 +08:00
这个量级基本上大多数服务器都很轻松能扛下来嘛, Linux 修改一下 open file 的 limit 就好了
|
4
powergx 2016-11-19 22:16:56 +08:00 via iPhone
intel 3700 ssd 一块搞定,为了安全最好 raid1
|
5
qq915458022 OP @abelyao 会错开一两秒。。 sql 非常简单,就是基本的 Update 一格。 mysql 在本地,服务器还没租所以也不知道时间。。
我主要是担心 cpu 吃不消 一般这种 CPU 和内存该配多大啊? |
6
qq915458022 OP @ipconfiger 谢谢了,那我租阿里 2 核 2G 够吗?
|
7
qq915458022 OP @powergx 租服务器
|
8
qq915458022 OP @prondtoo 刷单的话服务器的承载能力就不是我考虑的了😂
|
9
powergx 2016-11-19 22:54:38 +08:00 via iPhone
@qq915458022 阿里的磁盘 大概几十 ipos ,你要么放到 memcache /redis ,要么独立开数据库服务
|
10
txlty 2016-11-19 22:56:16 +08:00
最好优化下架构,把这个 update 缓进内存。
|
11
ipconfiger 2016-11-19 23:07:19 +08:00
@qq915458022 最好用 SSD 的 VPS, 不然 MySQL 装本地性能堪忧.
另外如果每次请求都有一次 update 的请求的话, 那基本就是在考 mysql 的性能了, 加缓存什么的治标不治本, 除非你的服务请求的频度是根据时间还有不同, 分了峰值和谷值的. 有很多情况还不清楚, 所以暂时没法给你进一步的建议 |
12
qq915458022 OP @ipconfiger 使用阿里的独立数据库呢?
|
13
qq915458022 OP @powergx 我也觉得独立数据库比较可行,但是阿里的独立数据库是内网的吗?网络延迟如何?
|
14
ipconfiger 2016-11-19 23:22:09 +08:00
@qq915458022 看你独立数据库服务器选的等级咯, 我觉得你还是先从访问模式的分析开始比较好, 你的业务什么访问模式都不清晰的情况下盲目做架构基本都跟找死没区别, 除非钱多, 用服务器来堆
|
15
moult 2016-11-19 23:30:41 +08:00
1 、如果更新的是同一行记录的话,或者就那么几行的话,可以用 Redis 缓存一下更新请求,然后汇总之后放到 SQL 上面。
2 、如果更新记录不固定的话,可以在给更新请求加个队列,把 4K 的请求分散到 5 秒,不就是 800QPS 了。 |
16
shiny 2016-11-19 23:33:09 +08:00
擦车做的好,低配机器轻松扛下来。做得不好,主要看 io 的。
|
17
qq915458022 OP @ipconfiger 软件性质比较敏感,不好细说。。
但也就是很简单的用 php update 一下 源码: http://ofhr82r8c.bkt.clouddn.com/%E6%97%A0%E6%A0%87%E9%A2%98.png |
18
qq915458022 OP @moult 那就直接开一个 redis 的数据库应该就可以吧?
|
19
ipconfiger 2016-11-20 00:06:05 +08:00
@qq915458022 我是说的访问模式, 比如你说的每 5 秒陆续会产生 4K 次请求, 那么是一直都是这个频度还是峰值是这个频度然后会有一段时间没有这么高的频度
|
20
qq915458022 OP @ipconfiger 一直保持
|
21
billlee 2016-11-20 00:36:14 +08:00
如果均匀分布的,那么 IOPS 是 800 s^-1, 如果要持久化到磁盘就必须要用 SSD.
如果可以放弃持久性要求,可以用 redis 或者把 innodb_flush_log_at_trx_commit 设置成 0. |
22
qq915458022 OP @billlee 我先上个 ssd 试试吧
实在不行就准备弄分布式了🌚 |
23
ipconfiger 2016-11-20 00:54:21 +08:00
@qq915458022 如果一直是这个频度的话, 基本上压力都是在数据库上了, 前端加什么都不好使, 先上个阿里云的 RDS 自己测一下 TPS, 能超过 1000 就 ok, 可以从最小规格的开始实验.
我在网上找到一个评测文章你可以参考一下: http://chuansong.me/n/2057150 另外, 如果全是 update, 而且 MySQL 测试出来不 满足 1000 的 TPS, 比如只有 200(原来年幼无知的时候在阿里云的最挫的 VPS 上本机装 mysql 测出来的结果). 那么可以用 redis 来做个对列, 如果光用对列是没用的, 因为写入数据库的频度始终比来数据的小, 所以对列会一直堆积耗光内存, 我原来做的对列是可以合并 update 请求的, 比如用 update 一个计数作为例子, 如果发现前面有未执行的 update 的值, 就把几次请求合并成一次数据库写入, 这样子数据库就不需要那么高的 TPS 了. |
24
qq915458022 OP @ipconfiger 因为数据是实时的而且要能在后台实时反应出来。。如果用内存积压的方法还要再从内存中读出来,感觉很麻烦。
目前配置可以往上堆,但是日后用户可能还要增长几倍(现在是测试小组 4000 人🌚),又只有一台服务器,所以有点伤感😂 |
25
qq915458022 OP @ipconfiger 其实也可以考虑合并呢。。隔 5s update 一次也会缓解很多,而且这下只考内存了
|
26
billlee 2016-11-20 01:25:18 +08:00
@ipconfiger 其实不需要在逻辑上对 UPDATE 请求做合并,只要把一串 UPDATE 放到一个 transaction 里去执行,速度就会快很多了吧,瓶颈一般是每次提交事务时 flush redo log 产生的 IO 操作。
|
27
fuxkcsdn 2016-11-20 12:22:11 +08:00 1
1 , SELECT * FROM userstatus 改掉,只取要用到的字段,还有,如果 phone 字段不是主键或者没有唯一索引的话, SQL 语句后面加上 LIMIT 1 (除非你的业务逻辑存在取多条记录的可能)
2 , UPDATE 语句打印 explain 出来看看(需要 MySQL 5.6 以上),可能的话把 UPDATE 语句完整的贴出来 BTW ,可以 isset($_GET['phone'], $_GET['sim'], $_GET['group']) && is_numeric($_GET['phone']) && is_numeric($_GET['sim']) && .... |
28
billwang 2016-11-20 12:32:20 +08:00
一般来说,试一下,扛得住就行,看不住再升级。:)
|
29
ipconfiger 2016-11-20 12:56:05 +08:00
@billlee 因为逻辑上来说只需要同步最终状态所以合并处理是最优的, 这个方案是原来做游戏服务器的时候用的, 主要的数据操作都在内存完成, 往数据库存只是为了持久化, 那么其实只需要持久化最终状态即可
|
30
kaneg 2016-11-20 13:53:21 +08:00 1
看了楼主发的代码截图,其实就是在数据库中持久化以 phone 为 key , owner 和 sim 为 value 的一个 map ,而这个 map 的大小为 4k 。所以最简单的办法就是在内存中保持这个 map ,新来的请求就只是更新这个 map 。而这个 map 多长时间刷新到数据库就看你的数据库的压力承受能力。
如果要读取用户的状态,只要先在内存 map 中查,能查到这就是最新状态,查不到再在数据库中读取。 这样下来,数据库的 IO 压力是可调整的。而能不能抗得住 5 秒内 4k 的 http 请求主要看服务器的 CPU 了。 |
31
quericy 2016-11-20 14:35:12 +08:00 1
17 楼是源码么...
单用 is_numeric 过滤,可以被 16 进制绕过,某些情况下可以注入的... |
32
goodryb 2016-11-20 15:32:17 +08:00
30 说的有道理,不过不想这么复杂的话,还是建议用 RDS 测试一下,先买个按量的实例,扛不住了就换个高规格的,没问题之后再买个包年包月的
当然了,省事就是费钱,量上来之后不行买高规格就搭配 redis 做缓存,没必要这么纠结 |
33
qq915458022 OP @quericy 谢谢提醒,已经换成 is_int
|