系统性能调优-学习笔记1

基本知识

大型网站架构设计必备的三板斧:

  • 高性能架构设计: 熟悉系统常见性能优化手段比如引入 读写分离、缓存、负载均衡、异步 等等。
  • 高可用架构设计 :CAP理论和BASE理论、通过集群来提高系统整体稳定性、超时和重试机制、应对接口级故障:降级、熔断、限流、排队。
  • 高扩展架构设计 :如何拆分系统。按照不同的思路来拆分软件系统,就会得到不同的架构。

基本原则

合适优于先进 > 演化优于一步到位 > 简单优于复杂

常见的性能优化策略

性能优化之前我们需要对请求经历的各个环节进行分析,排查出可能出现性能瓶颈的地方,定位问题。

下面是一些性能优化时常见问题:

  1. 当前系统的SQL语句是否存在问题?
  2. 当前系统是否需要升级硬件?
  3. 系统是否需要缓存?
  4. 系统架构本身是不是就有问题?
  5. 系统是否存在死锁的地方?
  6. 数据库索引使用是否合理?
  7. 系统是否存在内存泄漏?
  8. 系统的耗时操作进行了异步处理?

4S方法设计系统

概述

所谓4S分析法中的4S是指:
Scenario(场景),Service(服务),Storage(存储),Scale(扩展)。
接下来,我们结合4S分析法来具体回答一道常见系统设计题:如何设计一个推特?

第一步:Scenario 场景

在这一步,需要考虑:需要设计哪些功能(也可以自己想),需要承受多大的访问量?
首先可以把Twitter的功能一个个罗列出来,很显然你无法在45分钟的面试中完成所有功能的设计,所以需要筛选出核心功能(Post a Tweet,Timeline,News Feed,Follow/Unfollow a user,Register/Login)。
然后需要继续考虑系统承受的QPS大概是多少?需要考虑并发用户,读频率(Read QPS)以及写频率(Write QPS)。记住重要的是你的思考和计算过程而不是计算结果。

第二步,Service服务

所谓服务可以认为是逻辑处理的整合,对于同一类问题的逻辑处理可以归并到一个服务中。这一步实际上就是将整个系统细分为若干个小的服务。
根据第一步选出的核心功能,我们可以将推特拆分成如下的几个服务:

第三步,Storage 存储

接下来就是4S分析法中最重要的一部分,存储。根据每个服务的数据特性选择合适的存储结构,然后细化数据表结构。
系统设计中可以选择的存储结构一般有三大类:数据库系统,文件系统,缓存系统。其中数据库系统又分为关系型数据库(SQL Database)和 非关系型数据库(NoSQL Database)。

确定存储结构后,我们需要细化数据表结构,面试中可以通过画图展示数据存储和读取的流程。

用过前3个步骤的分析,我们已经得到了一个可行方案,注意是Work Solution而不是Perfect Solution,这个方案可以存在很多待解决的缺陷。

第四步,Scale 扩展

这一步主要分两部分:

  • 一个是优化和迭代设计,包括解决设计缺陷,更多功能设计,后台管理功能以及一些特殊情况如何处理;
  • 另一个是维护,包括系统的鲁棒性和扩展性,比如有一台服务器/数据库挂了怎么办?如果有流量暴增,如何扩展?

U型思考介绍-1

什么是U型思维呢?

U型思维是指先向下挖掘出问题本质,然后基于本质再来做决策的思考方式。它与上面直线式的思考相对应,因为思维链路有点像U,所以叫它U型思维,也可以叫它本质思考或者第二性思考。

U-Theory

既然 U 型思维这么好,那么我们又如何能由直线思考升级到U型思考,从而拥有一眼洞穿本质的能力呢?

其实和学习其他新生事物一样的道理,我们首先需要掌握科学系统的训练方法,其次通过刻意练习,让U型思考这种思维方式形成习惯以后,存储到我们潜意识层,它也就变成了我们操作系统上又一个常用的思维框架 。后续每当你遇到方向性问题时,U型思维这个 思维框架 就会自动运转起来,它就是专门用来解决战略方向性问题的,帮助我们确立前行方向。所以擅长U型思考的人,往往也是战略高手。

具体的训练步骤可以分为以下三步:

  1. 找核心问题
  2. 找本质原因
  3. 找解决方案

助记词:
先问后挖,不破不立

conda 创建、激活、退出、删除虚拟环境 (Anaconda)

在Anaconda中conda可以理解为一个工具,也是一个可执行命令,其核心功能是包管理与环境管理。所以对虚拟环境进行创建、删除等操作需要使用conda命令。

conda 本地环境常用操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#获取版本号
conda --version 或 conda -V

#检查更新当前conda
conda update conda

#查看当前存在哪些虚拟环境
conda env list 或 conda info -e

#查看--安装--更新--删除包

conda list:
conda search package_name# 查询包
conda install package_name
conda install package_name=1.5.0
conda update package_name
conda remove package_name

conda创建虚拟环境

1
2
3
4
5
6
7
8
9
10
#创建名为your_env_name的环境
conda create --name your_env_name
#创建制定python版本的环境
conda create --name your_env_name python=2.7
conda create --name your_env_name python=3.6
#创建包含某些包(如numpy,scipy)的环境
conda create --name your_env_name numpy scipy
#创建指定python版本下包含某些包的环境
conda create --name your_env_name python=3.6 numpy scipy

激活虚拟环境

1
2
3
4
5
6
#Linux
source activate your_env_name

#Windows
activate your_env_name

退出虚拟环境

1
2
3
4
5
6
#Linux
source deactivate your_env_name

#Windows
deactivate env_name

删除虚拟环境

1
2
3
conda remove -n your_env_name --all
conda remove --name your_env_name --all

复制某个环境

1
conda create --name new_env_name --clone old_env_name

在指定环境中管理包

1
2
3
4
conda list -n your_env_name
conda install --name myenv package_name
conda remove --name myenv package_name

使用国内 conda 软件源加速

1
2
3
4
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/
conda config --set show_channel_urls yes

FRP内网穿透实际操作

为什么要内网穿透

内网穿透,也即 NAT 穿透,进行 NAT 穿透是为了使具有某一个特定源 IP 地址和源端口号的数据包不被 NAT 设备屏蔽而正确路由到内网主机。 说人话就是我们想在不连接家里的wifi的情况下访问我们家里面的电脑和其他设备时,由于家庭宽带没有固定的公网ip使得我们无法向访问云服务器一样 直接访问,这时候我们就需要使用到内网穿透技术,让我们在其他网络下也能访问到处于内网环境的设备。而内网穿透的工具也有很多如: - 花生壳 - nat123 - ngrok - frp,本文主要讲FRP的搭建和使用,这个方案基本免费,仅需要一个有公网IP的服务器。我用的是腾讯云的服务器。

什么是FRP

Frp (Fast Reverse Proxy) 是比较流行的一款。FRP 是一个免费开源的用于内网穿透的反向代理应用,它支持 TCP、UDP 协议, 也为 http 和 https 协议提供了额外的支持。你可以粗略理解它是一个中转站, 帮你实现 公网 ←→ FRP(服务器) ←→ 内网 的连接,让内网里的设备也可以被公网访问到。仓库地址

安装FRP

More...

系统地测试变化的策略

有时很难确定一个改变(例如,新的指示或新的设计)是使系统变得更好还是更糟。通过查看一些示例可能可以暗示哪个更好,但是对于小样本量来说,很难区分是真正的改进还是随机运气。也许这个改变对某些输入的性能有所帮助,但对其他输入的性能有所损害。
评估程序(或“评估”)对于优化系统设计是有用的。好的评估具备以下特点:

  • 代表真实世界的使用情况(或至少具备多样性)
  • 包含许多测试案例以获得更大的统计能力(请参考下表以获取指导方针)
  • 易于自动化或重复执行

输出的评估可以由计算机、人类或二者结合来进行。计算机可以通过客观标准(例如,具有单一正确答案的问题)自动化评估,也可以通过一些主观或模糊标准进行评估,其中模型的输出由其他模型查询来评估。OpenAI Evals是一个开源软件框架,提供了创建自动评估的工具。
基于模型的评估在存在一系列可能的输出,且这些输出在质量上被认为是相等的情况下(例如,对于需要长答案的问题)是有用的。基于模型的评估与需要人类进行评估的情况之间的界限是模糊的,并且随着模型能力的提升,这个界限不断变化。我们鼓励进行实验,以确定基于模型的评估在您的用例中的效果如何。

通过与黄金标准答案对比评估模型输出结果

假设我们已知问题的正确答案应该涉及到一组特定的已知事实。然后我们可以使用模型查询来计算答案中包含的必要事实的数量。

例如,使用以下系统消息:

Role Prompt
SYSTEM You will be provided with text delimited by triple quotes that is supposed to be the answer to a question. Check if the following pieces of information are directly contained in the answer:
- Neil Armstrong was the first person to walk on the moon.
- The date Neil Armstrong first walked on the moon was July 21, 1969.
For each of these points perform the following steps:
1 - Restate the point.
2 - Provide a citation from the answer which is closest to this point.
3 - Consider if someone reading the citation who doesn’t know the topic could directly infer the point. Explain why or why not before making up your mind.
4 - Write “yes” if the answer to 3 was yes, otherwise write “no”.
Finally, provide a count of how many “yes” answers there are. Provide this count as {“count”: }.
More...

使用外部工具的策略

使用基于嵌入的搜索实现高效的知识检索

有时候,当我们明确指示模型在得出结论之前从基本原理进行推理时,我们可以获得更好的结果。例如,假设我们希望模型评估学生对一个数学问题的解答。最直接的方法是简单地问模型学生的解答是否正确

如果提供外部信息作为模型输入的一部分,模型可以利用这些信息。这可以帮助模型生成更具见解和最新的回答。例如,如果用户问一个关于特定电影的问题,将关于电影的高质量信息(如演员、导演等)添加到模型的输入中可能会很有用。可以使用嵌入(embeddings)来实现高效的知识检索,以便在运行时动态地将相关信息添加到模型输入中。

文本嵌入是可以衡量文本字符串之间关联性的向量。相似或相关的字符串之间的距离比不相关的字符串更近。这一事实,加上存在快速向量搜索算法,意味着可以利用嵌入来实现高效的知识检索。具体而言,可以将文本语料库分割成多个块,然后对每个块进行嵌入和存储。然后,可以对给定的查询进行嵌入,执行向量搜索以找到与查询最相关的文本块(即在嵌入空间中最接近的文本块)。

OpenAI Cookbook中可以找到示例实现。参考“指示模型使用检索到的知识来回答查询”策略,了解如何使用知识检索来最大程度地减少模型捏造不正确事实的可能性的示例。

使用代码执行进行更准确的计算或调用外部API

GPT模型本身不能可靠地执行算术或长时间计算。在需要进行这类计算的情况下,可以指示模型编写和运行代码,而不是进行自己的计算。特别是,可以指示模型将需要运行的代码放入指定的格式,例如三个反引号(triple backtics)。在生成输出后,可以提取并运行代码。最后,如果需要的话,可以将代码执行引擎(例如Python解释器)的输出作为下一个查询的模型输入。

Role Prompt
SYSTEM You can write and execute Python code by enclosing it in triple backticks, e.g. code goes here. Use this to perform calculations.
USER Find all real-valued roots of the following polynomial: 3x**5 - 5x4 - 3x3 - 7x - 10.

另一个代码执行的良好用例是调用外部API。如果向模型传授API的正确使用方法,它可以编写使用该API的代码。通过向模型提供API的文档和/或代码示例,可以告诉它如何使用该API。

Role Prompt
SYSTEM You can write and execute Python code by enclosing it in triple backticks. Also note that you have access to the following module to help users send messages to their friends:
‘’‘python
import message
message.write(to=“John”, message=“Hey, want to meetup after work?”) ‘’’

给GPTs一些时间来“思考”的策略

指示模型在草率得出结论之前自己解决问题

有时候,当我们明确指示模型在得出结论之前从基本原理进行推理时,我们可以获得更好的结果。例如,假设我们希望模型评估学生对一个数学问题的解答。最直接的方法是简单地问模型学生的解答是否正确

Role Prompt
SYSTEM Determine if the student’s solution is correct or not.
USER Problem Statement: I’m building a solar power installation and I need help working out the financials.
- Land costs $100 / square foot
- I can buy solar panels for $250 / square foot
- I negotiated a contract for maintenance that will cost me a flat $100k per year, and an additional $10 / square foot
What is the total cost for the first year of operations as a function of the number of square feet.
Student’s Solution: Let x be the size of the installation in square feet.
1. Land cost: 100x
2. Solar panel cost: 250x
3. Maintenance cost: 100,000 + 100x
Total cost: 100x + 250x + 100,000 + 100x = 450x + 100,000
ASSISTANT The student’s solution is correct.

但学生的解答实际上是不正确的!我们可以通过提示模型首先生成自己的解答来成功让模型注意到这一点。

More...

将复杂任务分解为简单的子任务的策略

使用意图分类来识别用户查询的最相关指令

对于需要处理不同情况的大量独立指令的任务,首先对查询类型进行分类,并使用该分类确定所需的指令,可以带来一些好处。这可以通过定义固定的类别和硬编码与处理给定类别任务相关的指令来实现。该过程还可以递归应用于将任务分解为一系列阶段。这种方法的优点在于每个查询只包含执行任务的下一个阶段所需的指令,这可能导致与使用单个查询执行整个任务相比较低的错误率。这还可以降低成本,因为较大的提示运行成本更高(请参阅定价信息)。

例如,假设对于客户服务应用程序,查询可以有以下有用的分类方式:

Role Prompt
SYSTEM You will be provided with customer service queries. Classify each query into a primary category and a secondary category. Provide your output in json format with the keys: primary and secondary.
Primary categories: Billing, Technical Support, Account Management, or General Inquiry.
Billing secondary categories:
- Unsubscribe or upgrade
- Add a payment method
- Explanation for charge
- Dispute a charge
Technical Support secondary categories:
- Troubleshooting
- Device compatibility
- Software updates
Account Management secondary categories:
- Password reset
- Update personal information
- Close account
- Account security
General Inquiry secondary categories:
- Product information
- Pricing
- Feedback
- Speak to a human
USER I need to get my internet working again.

根据客户查询的分类,可以为GPT模型提供一组更具体的指令来处理下一步操作。例如,假设客户需要“故障排除”的帮助。

More...

提供参考文本的策略

指示模型使用参考文本回答问题

如果我们能够向模型提供与当前查询相关且可信的信息,那么我们可以指示模型使用提供的信息来组织回答。

Role Prompt
SYSTEM Use the provided articles delimited by triple quotes to answer questions. If the answer cannot be found in the articles, write "I could not find an answer.”
USER <insert articles, each delimited by triple quotes>
Question:

考虑到GPT模型的上下文窗口有限,为了应用这个策略,我们需要一种动态查找与所提问题相关的信息的方法。嵌入可以用来实现高效的知识检索。有关如何实施这一策略的详细信息,请参阅“使用基于嵌入的搜索来实现高效的知识检索”策略。

指示模型使用参考文本中的引用进行回答

如果输入已经补充了相关知识,可以要求模型通过引用提供的文献中的段落来添加引用。请注意,可以通过在提供的文献中进行字符串匹配来对输出中的引文进行程序验证。

Role Prompt
SYSTEM You will be provided with a document delimited by triple quotes and a question. Your task is to answer the question using only the provided document and to cite the passage(s) of the document used to answer the question. If the document does not contain the information needed to answer this question then simply write: “Insufficient information.” If an answer to the question is provided, it must be annotated with a citation. Use the following format for to cite relevant passages ({“citation”: …}).
USER <insert articles, each delimited by triple quotes>
Question:

请我喝杯咖啡吧~

支付宝
微信