12
回答
问几个高并发方面的解决方案
注册华为云得mate10,2.9折抢先购!>>>   

1. Memcache 失效产生的雪崩问题。

问题描述:Memcache在Mysql前做了一级缓存,每次去MySQL查询的话大约耗时3秒,而每秒钟大约有100秒请求进来,这时,如果恰好memcache缓存过了有效期,那么其中一个请求肯定要穿透到Mysql去查询,而这时候的请求去查memcache的时候也是查不到的,于是这些请求也去Mysql查了,这样造成了短时间内的大量MySql查询。



2. MySQL 主从复制迟延,导致数据同步问题。

问题描述: MySQL 部署了主从复制,并且应用了读写分离特性,写到主库,从库读取。有个逻辑是从数据库中查询最大值,加1后写到主库里,而因为从库的迟延问题,查到的数据是旧的,加1后应该也是旧的,因此INSERT到主库的数据也是旧的,可能发生值重复插入问题。



3. MySQL 分表问题

问题描述:有个千万级以上的用户表,记录了Email值、用户名,要完成用户登录动作,用户可以输入用户名或者Email都能完成登录动作。因为用户数量较多,查询时比较慢,所以想分表,此时如果按着用户名规则分表,那么email就会无序的分布在其他表中,这样就加重了email的查询,反之亦然。

举报
木川瓦兹
发帖于3年前 12回/1K+阅
共有12个答案 最后回答: 3年前

1:我感觉对于第一问题还是当数据不存在时,全部查询落到了数据库,那么其实你可以返回一个Null,把这个值缓存,并且考虑好过期时间

2:读写分离 其实起不到什么作用,因为从断还负责着同步数据问题,所以也存在写,如果只读从那么肯定会有延迟问题,对于敏感及时问题,是否可以这样,当写数据和读数据一起,就同时访问主,如果只读,那么就请求从,前提是你允许有延迟问题。

3:是否可以把email 用户名 分成两个表,对两个表进行不同的hash查询

我其实也不是很懂

对于第一个问题,要对DAL层做封装,将缓存查找和数据库查找封装成一个接口,对外不区分数据库和缓存查找。原理是当缓存失效时,第一次请求DAL将引发数据库查询,在查询之前创建一个FutureTask,异步任务,这是Java中的概念,别的语言也有类似的。然后在将这个FutureTask和查询语句关联保持,之后再有请求过来之后,发现已有相同的访问数据库的查询,就不要再发相同的查询。也可以在Memcached里加一个标记以表示这个数据库查询正在进行,以避免重复查询

1.如果真有这种业务的话,memcache失效还是别做了,有更新的时候就同时更新缓存

2. 这个的话,自己维护一个当前最大ID就行了,具体用redis的 inc命令什么的都可以

3. 做一个 email -> username  的映射表

关于第二个问题,不知道你是采用了什么读写分离软件

但是应该都须有强制将sql语句发往主库的功能吧

例如atlas的话,SQL语句前增加 /*master*/ 就可以将读请求强制发往主库

一、一般两种方式  1.主动拉:发现数据过期就调一个异步去取数据并打上标记(一般用时间戳)且设置过期时间,回来的时候按标记更新(避免出现特别异常的情况 所以需要比较标记) 看业务需求是否可以返回旧数据 2.主动缓存:缓存永不过期 而是在更新数据的时候同步更新缓存 这样相对来说 数据跟逻辑分离 比较容易控制. 还是要看业务需求取舍  

二、其实一般的更新都存在这个问题,只要主从同步不及时 在发出更新请求的同时 从库的旧数据被拿到再次发出更新请求也是会出现这种情况的 一般用版本号来预防一下 你这种情况要不就强制请求主库 要不就搞个临时表 对数值进行版本控制(例如时间戳)

三、要看业务数据的规则,既然有明确的email用户名 是否可以在第一层就按email以及用户名路由呢?然后是否可以根据hash分布?或者搞点简单的则 主要是要让数据平均分布 这样就能分摊请求压力

1. 电子商务、动态刷新频率高的系统。如果对数据一致性有要求,尽量不使用缓存。为保证数据的一致性,尽可能从数据库结构上优化查询性能(比如使用从库查询)。 或使用后台程序生成缓存,前台只负责读取缓存,不负责生成缓存,就可以避免雪崩的问题。

2. 如果对数据一致性有要求,必须强制主库读写。

3.mysql索引查询性能,不会因为数据体积变化性能急剧下降,我测试过包含20多个字段,5个索引字段的表,7000万记录情况下和1000万查询性能区别并不大,所以不必分表。

如果确实要分表,分别按用户名和email生成表,进行查询即可

顶部