4_单机服务端优化

重复提交优化:

  1. js层面,在用户点击提交订单后禁用按钮。
  2. 使用Redis incrde 原子性递增计数
//针对同一单生成固定唯一标识
orderNum=memberId+productId;

//条数加1
count = redis.increment(orderNum, 1); //添加过程中会返回当前总数
if (count == 1) {
	//设置有效期2秒
  redis.expire(orderNum, 2, TimeUnit.SECONDS);
}

if (count > 1) {
   resultMap.put("retCode", "500");     
   resultMap.put("retMsg", "请不要重复提交订单");
   return resultMap;
}

操作同一条数据优化

FOR UPDATE注意事项

  • 在mysql中FOR UPDATE时,如果查询条件带有主键会锁行数据,如果没有则会锁表数据。
  • 如果查询一条正在执行事务的数据时使用了FOR UPDATE 此时程序会进行阻塞,直到事务进行提交或者回滚时才会查询出结果。

FOR UPDATE使用场景

当商户取消某一个订单时,此时用户正在支付此笔订单,当程序运行到查询此笔【待支付】订单金额时需要使用 FOR UPDATE ,然而程序一直会阻塞,直到商户取消完订单【已取消】事务提交后,此时查询结果会显示查询订单不存在,避免了错误支付的情况。

大表数据查询

优化前:

聚簇索引:就是存放指向磁盘的叶子节点

慢的原因:需要查询300005次索引节点,查询300005次聚簇索引的数据,最后再将结果过滤掉前300000条,取出最后5条。MySQL耗费了大量随机I/O在查询聚簇索引的数据上,而有300000次随机I/O查询到的数据是不会出现在结果集当中的。

mysql> select * from test where val=4 limit 300000,5;
+---------+-----+--------+
| id      | val | source |
+---------+-----+--------+
| 3327622 |   4 |      4 |
| 3327632 |   4 |      4 |
| 3327642 |   4 |      4 |
| 3327652 |   4 |      4 |
| 3327662 |   4 |      4 |
+---------+-----+--------+
5 rows in set (15.98 sec)

优化后:

mysql> select * from test a inner join (select id from test where val=4 limit 300000,5) b on a.id=b.id;
+---------+-----+--------+---------+
| id      | val | source | id      |
+---------+-----+--------+---------+
| 3327622 |   4 |      4 | 3327622 |
| 3327632 |   4 |      4 | 3327632 |
| 3327642 |   4 |      4 | 3327642 |
| 3327652 |   4 |      4 | 3327652 |
| 3327662 |   4 |      4 | 3327662 |
+---------+-----+--------+---------+
5 rows in set (0.38 sec)

快的原因:先沿着索引叶子节点查询到最后需要的5个节点,然后再去聚簇索引中查询实际数据。这样只需要5次随机I/O,

缓存层

  • elasticsearch:搜索引擎、分布式日志存储
  • redis:
    • String : 分布式id、砍价(用户每天只能投票一次)、地区存储
    • Hash:车三项、用户四要素
    • List:朋友圈点赞按顺序展示、关注列表按照顺序展示
    • Set:网站每日的IP访问数量、用户首次登陆推送喜欢的商品
    • Sorted_set:排行榜

3 分库分表

分库
  • 会涉及到分布式事务来保证数据的一致性
  • 在生成唯一单号时要在中台服务生成供后台使用
分表
  • 通过哈希算法均匀的分配到不同的表里面
  • Mycat它是数据库中间件,可通过它来组织数据库的分离读写和分库分表,客户端通过它来访问下层数据库,还会涉及数据同步,数据一致性的问题。
水平拆分表

就是把一个表的数据拆分到多个库的多个表里面去。这里面的每个库的表结构都是一样的,只不过是表中存放的数据不一样,每个库表的数据汇总起来就是全部数据。

垂直拆分表

就是把一个有很多字段的表给拆分成多个表或者多个库上面去,每个库表的结构都不一样,每个库表都包含部分字段。一般来说,会将较少的访问频率很高的字段放到一个表里面去,然后将较多的访问频率很低的字段放到另外一个表里面去。

分库分表实例
  1. 分销商城订单分库分表,拆分十个表分别为order_1,order_2...,订单详情表也要拆分,还要拆分两个库data_1,data_2
  2. 编号为0-4在data_1库,编号为5-9在data_2库,订单服务的表只需要订单总表和订单详情表拆分,别的表只要一份,在对应的库里即可。
  3. 当用户下单购买时,以用户id最后一位为标准存到对应的库里的对应表里,并且在es里面维护一份数据方便运营端查询,es要存储这条数据属于哪个库里的哪张表
  4. 当订单状态发生改变时,也要同时维护es里的数据
  5. 当运营端统计订单总量时,只需要查询es即可分页、搜索,修改都支持

4 高问量处理

分流
熔断
降级
监控
日志
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值