项目 ThinkPHP+MySQL
具体是这样,有个文章后台,每条文章有个字段存着已读人员,是数组形式存着 UID,然后 json_encode 存进数据库。
当访问文章的时候,读取该字段,json_decode 后,判断当前 UID 是否在数组中,不存在则 push 上去,然后再 json_encode 进数据库。
问题就是当出现高并发的时候(最高大概也就每秒上千个访问),会不会出现多个 PHP 进程同时读取了该字段,然后又同时写入数据库,导致部分数据被覆盖过去。
同时也想知道有哪些资料可以了解一下 PHP 以及 MySQL 的线程、执行顺序问题。
1
feiyuanqiu 2018-06-19 13:58:24 +08:00
跟 PHP 没关系,数据库层面可以看看悲观锁、乐观锁,小流量网站用悲观锁一般就解决了
|
2
KgM4gLtF0shViDH3 2018-06-19 14:02:25 +08:00 via iPhone
用队列
|
3
feiyuanqiu 2018-06-19 14:03:29 +08:00
不过我觉得其实应该把已读人员单独弄张表,表里面做个 文章 ID + 用户 ID 的唯一键,插入冲突就表示已经存在这个关系了,直接返回已存在的已读关系,这样接口也幂等了
|
4
allenhu 2018-06-19 14:28:22 +08:00
每秒上千个访问, 你的 uid 字段存得下么?
|
5
cstome OP @allenhu #4 实际情况是文章刚发布的时候会有大概最高每秒 1000 的高并发,后面会慢慢下降,UID 也不长,用 TEXT 类型完全够存。
|
6
puritania 2018-06-20 00:14:50 +08:00 via iPhone
强行制造并发……
|
7
cstome OP @feiyuanqiu #3 之前想过这么弄,但是考虑到后面可能数据库条数比较多,影响速度,就没这么弄了。
|
8
feiyuanqiu 2018-06-20 15:07:09 +08:00 1
@cstome
怕数据库慢就用 redis,用文章表字段存这个真不太好,我现在能想到的问题就不少了: 1. 会影响文章表的查询效率,尤其是在阅读人数变多之后,每条文章记录都平白无故增加几 K 的内容 2. 无法检索用户已读的文章,因为是 json_encode 到 text 里面的,没法做查询,以后产品有这个需求的时候又要改又要做数据迁移 3. 更新阅读记录效率低下,要先检索出文章,再 decode,再往里面添加内容,再 encode,再更新,还要加锁放并发;比直接插入一条阅读记录效率低多了 4. text 的长度是 65536,你的 uid 长度是多少,假设是 32,最多可以存 2048 个 uid,实际肯定存不了这么多,因为你还做了 json_encode,也就是一篇文章上限只能存一千多个阅读记录 |