怎么设计一套日千万数据的系统
面试官:有一套日处理千万级系统,你该怎么设计
项目技术栈:Php+Redis+Mysql+RobbitMQ+ES等
1.表结构设计符合三范式
2.索引设计给关键字段(where,orderBy,groupBy,Join操作中使用字段)增加索引,使用explain分析SQL,避免全表扫描
3.业务逻辑层,耗时且无需直接反馈用户前端采用异步处理,例如队列,后端进程监控队列处理对应操作
4.因为数据量大所以可能对表结构分表分库,读写分离等架构,增加项目并发性和扩展性
5.如果业务需要全文检索,则可以把需要检索的数据压入ES,后端对ES数据读取检索
6.业务前端采用jwt前后端分离,nginx做多台服务器做负载均衡
7.使用Redis对热门数据缓存,缓解数据库压力
8.对接口限流必要情况可采用熔断,防止突发状况
如有必要采用分布式架构或微服务架构,对业务逻辑水平、垂直分割,使用MySQL Cluster将数据分散存储到不同服务器
如果要同时处理一批数据,怎么处理
使用Pluck切片查询或使用游标查询然后分批处理数据
ES如何同时写入百万级数据
Elasticsearch 是一个分布式搜索和分析引擎,具有快速、高效的数据写入和检索能力。要同时写入百万级数据,可以采用以下几种方式:
- 使用批量写入 API:Elasticsearch 提供了一个批量写入 API,可以将多个文档一次性写入到 Elasticsearch 中。这种方式可以大大减少网络和服务器开销,并提高写入性能。例如,可以使用如下代码将多个文档批量写入 Elasticsearch:
1 | $params = []; |
在上面的代码中,使用
bulk
方法将多个文档批量写入 Elasticsearch。
使用并发写入:如果要写入大量数据,可以使用并发写入的方式,将数据分成多个批次并发写入 Elasticsearch 中。这种方式可以充分利用服务器的资源,并提高写入性能。例如,可以使用多线程或协程等技术来实现并发写入。
调整 Elasticsearch 集群设置:如果要写入大量数据,可以根据实际情况调整 Elasticsearch 集群的设置,例如,增加 Elasticsearch 集群节点、调整写入缓存等。
总之,要同时写入百万级数据,需要根据具体的业务需求和数据规模,采用适当的方式来优化写入性能。
常见秒杀场景怎么设计
秒杀场景是一种高并发、高性能要求的场景,需要针对性地设计和优化。下面介绍一些常见的秒杀场景设计思路:
- 减少数据库压力:在秒杀场景中,数据库通常是瓶颈,为了减少数据库的压力,可以使用缓存、队列等技术,将部分数据或操作从数据库中转移到内存或其他组件中。例如,可以使用 Redis 缓存库存信息、订单信息等,使用消息队列处理下单请求,减少数据库的压力。
- 预热缓存:在秒杀开始前,可以提前加载部分数据到缓存中,避免请求落到数据库上,造成数据库的压力。例如,可以提前加载商品信息、库存信息等到缓存中,缓解短时间内的请求压力。
- 使用分布式系统:为了支持高并发和高可用性,可以使用分布式系统来设计和实现秒杀场景。例如,可以使用分布式缓存、分布式数据库、负载均衡等技术,将系统的压力和请求分散到多台服务器上,提高系统的性能和可用性。
- 限流措施:为了保护系统和避免恶意攻击,可以使用限流措施,例如设置最大并发数、限制用户的访问频率等,以防止恶意请求对系统造成影响。
- 异步处理:为了提高系统的性能和响应速度,可以使用异步处理技术,例如使用消息队列等组件将下单请求异步处理,避免阻塞请求线程,提高系统的并发能力。
- 分批次处理:为了避免系统的崩溃和数据异常,可以将秒杀活动分批次进行处理,每次处理一定数量的请求,避免一次性处理过多的请求造成系统瘫痪。
总的来说,秒杀场景需要综合考虑性能、可用性、稳定性等多个方面的因素,需要使用一系列技术手段和设计思路来优化系统。
网站大并发场景常见处理手段
- 使用负载均衡(nginx ip或hash)
- 使用流控,具体可采用令牌算法,每秒请求N,单次请求即1/N,如果累计请求大于N,则后续请求返回403
- 使用Redis,APC等技术对热点数据缓存
- 采用Mysql集群
- 使用消息队列或定时任务处理异步化部分程序操作
- 数据库优化(数据库设计,索引优化,SQL语句优化)
为什么使用JWT
- 前后端分离,避免前端请求影响后端接口响应时间
- 无需在服务端存储用户认证信息,减轻服务器的存储压力和网络流量
- JWT使用数字签名算法进行加密和校验,可以防止信息被篡改和伪造
- JWT支持多语言和跨平台,可以在不同平台之间存储和传输身份信息
- JWT可以存储一些自定义用户信息,方便在不同服务之间共享用户信息,提高系统安全性和效率
- 简化系统的身份认证和授权流程,提高系统扩展性和灵活性
Epoll和Select有什么区别
Epoll 和 Select 都是常用的 Linux 下的多路复用技术,可以用于实现高性能的网络应用程序,但它们的实现方式有所不同,下面是它们的区别:
- 实现方式不同:Select 是采用轮询的方式实现多路复用,每次需要将所有的文件描述符都扫描一遍,效率较低。而 Epoll 是采用事件通知的方式实现多路复用,当有数据到来时,内核会主动通知应用程序,效率较高。
- 支持的连接数不同:Select 对于支持的连接数有限制,通常是 1024 个,而 Epoll 没有连接数限制,可以支持数十万个连接。
- 内存开销不同:Select 在内核中需要维护一个文件描述符集合,需要占用一定的内存空间,而 Epoll 只需要在触发事件时才需要在内存中保存相关信息,因此内存开销较小。
- 用户空间和内核空间交互次数不同:Select 每次需要将所有的文件描述符都扫描一遍,需要多次用户空间和内核空间的交互,而 Epoll 只需要在触发事件时进行一次交互,减少了用户空间和内核空间的交互次数,提高了性能。
总的来说,Epoll 在性能和扩展性方面优于 Select,特别是在支持大量连接的高并发场景下,Epoll 更加适用。但是,需要注意的是,Epoll 的实现比较复杂,需要较高的技术水平和经验。
如何分表分库
在数据库设计中,当单个表数据量过大时,为了提高查询性能和可维护性,需要将数据分散到多个表或者多个数据库中,这就是分表分库。
分表分库的实现方式有很多种,下面是一些常见的方法:
- 垂直分表:将一个大的表按照业务逻辑分为多个小表,每个小表只包含特定的字段。例如,将用户信息分为基本信息、扩展信息、权限信息等多个表。
- 水平分表:将一个大的表按照记录行分为多个小表,每个小表只包含部分记录。例如,将订单按照订单号或者时间分为多个表。
- 分库:将一个大的数据库按照业务逻辑分为多个小数据库,每个小数据库只包含特定的表或者特定的业务。例如,将订单和商品分别存储在不同的数据库中。
- 主从分离:将读写分离,将所有写操作集中在主数据库中,所有读操作都在从数据库中进行。这样可以减轻主数据库的压力,提高读取性能。
在实际应用中,需要根据具体的业务需求和系统性能进行选择和调整,需要考虑多个因素,例如数据量、读写比例、数据关联性等。同时,分表分库也需要对代码进行修改,以适应新的数据结构。
常用系统安全
- 如果遇到CC攻击,对接口限流,开启CDN5秒盾,封IP、User-agent
- 对参数过滤(html或SQL中特殊符合等)和验证
- SQL使用预处理,避免SQL拼接
- 避免使用高危函数,例如(exec,system等可执行命令的函数)
- DDOS可采用https和CDN方案