lamp进阶
前言:上一文说到,在lamp上简单的部署应用程序,wordpress和phpmyadmin
稍稍回顾一下,动态页面apche发往后端类PHP程序,其PHP本身提供能与后端mysql进行交互的驱动,使得PHP运行中的代码能与后端mysql互动(解释器本身无需与mysql交互,事实上是代码段涉及用户数据时,才需要进行交互)
一、PHP
1.1简介
PHP是通用服务器脚本编程语言,其只要是用于web开发以实现动态web页面。PHP自身需要将自己的代码运行在类虚拟机即解释器上,以实现跨平台通用性,不过,这样一来也就造成了性能下降。
除此外,它还是最早实现将脚本嵌入HTML源码文档中的服务器脚本语言。就web而言静态页面本身的HTML标签由apache提供(前端设计师),自然,动态页面便需要后端的应用程序添上HTML标签(类PHP程序员),但并非每个PHP程序员既能懂得PHP又懂得HTML、CSS等前端语言的,为此PHP专门设立了脚本,将二者分离,写前端的写前端,写PHP的写PHP,写完代码后交给脚本无需手动添上HTML标签。
PHP能够将代码直接嵌入至HTML中,纯HTML交由apache识别,纯PHP代码由解释器识别。
从echo "<h1>hello world!</h1>"到
<h1>
<?php>echo "hello world!"?>
</h1>
PHP的默认配置文件为/etc/php.ini,/etc/php.d/*.ini
配置文件(php.ini)在PHP启动时被读取,对于服务器模块的PHP,仅在WEB服务器启动时读取一次,对于CGI和CLI版本每次调用都会被读取。
注1:之前说过CGI架构时,PHP由服务器生成的子进程响应客户端,所以本质上配置文件也是在启动时被读取
注2:CLI命令行接口时,每当执行一次命令,CLI程序皆会自动加载配置文件
注3:PHP5.2+后能够为每个PHP版本提供不同的配置文件,linux上需在编译时手动指定配置文件
1.2 Zend Engine
早期在没有Zend Engine的时候,PHP要将源码转换为可执行的机器码效率十分的底下,需翻译一句执行一句。Zend Engine出现后将PHP代码处理过程分解成了两个阶段:分析PHP代码并将其转换为Zend opcode的二进制格式(类似JAVA字节码),并存储在内存上;第二阶段再使用Zend Engine执行opcode
opcode离机器码仅有一步之遥,且存储在内存之中,即相当与在未执行之前便开始了翻译,需要执行代码的时候进行极少的翻译步骤便可执行,比之原始的翻译一句执行一句效率不知道要高尚多少倍。
1.3 PHP的opcode
opcode是一种介于源码和机器码间的一种特殊的二进制格式,它是由PHP编译后的一种中间语言,类似JAVA的ByteCode或.NET的MSL。PHP执行PHP脚本代码一般会经过以下4步骤:
1、Scanning(Lexing)——将PHP代码转换为语言片段(Tokens)
2、Parsing——将Tokens转换为简单而有意义的表达式
3、Compilation——将表达式编译成Opcode
4、Execiution——顺次执行Opcode,每次一条,从而实现PHP脚本的功能
扫描 --> 分析 -->编译 -->执行
1.4 PHP加速
重点来了,上文所述,PHP首先编译成opcode。基于Php的特殊缓存扩展机制,或能将opcode存储在共享内存中,从而可以让同一段代码的后续重复执行时跳过编译阶段以提高性能。本质上来说,这些加速器并非真正提高opcode的运行速度,而仅是通过分析opcode并将通过重新编排以实现加速的目的。
常见的PHP加速器
Xcache:通过将opcode存储在共享内存中,以便跳过不同程序对重复的PHP代码编译
Memcached:高性能分布式缓存程序。memcached的安装位置位于应用程序和数据存储之间,它能够将需要存储的对象存储在RAM中。每次缓存命中中将替换到数据库的一次往返,使得应用程序响应更快、
APC(Alternative PHP Cache)它对php opcode进行缓存,从而减少执行时重新翻译的次数。不过这玩意,多年前便停止了维护,而且仅支持到PHP5.3
1.41 加速演示
PHP5.5+以下系统PHP还未内置加速可通过编译Xcache、APC等等手动为PHP进行加速。5.5+以上之后PHP内置opcache能对opcode进行加速(编译时需手动指定)。不过这之上还是有些区别,5.5版本的PHP opcache默认是关闭的需手动修改php.ini,而5.6采用的是模块化设计,配置文件不再是php.ini,php.d下的opcache.ini,且默认是开启。虽然,两个版本的配置文件不同但配置方式大同小异。
;模块
zend_extension=opcache.so ; Determines if Zend OPCache is enabled opcache.enable=1 ; Determines if Zend OPCache is enabled for the CLI version of PHP ;是否启动1为开启,0为关闭 ;opcache.enable_cli=0 ; The OPcache shared memory storage size. ;共享内存大小,单位MBzuizuidopcache.memory_consumptionzuida=128 ; The amount of memory for interned strings in Mbytes. ;暂存池中字串符占内存的总量,单位MB opcache.interned_strings_buffer=8 ; The maximum number of keys (scripts) in the OPcache hash table. ; Only numbers between 200 and 100000 are allowed. ;最大缓存文件数 opcache.max_accelerated_files=4000 ; The maximum percentage of "wasted" memory until a restart is scheduled. ;“浪费”内存的最大值,便会重启调度 ;opcache.max_wasted_percentage=5
首先对环境进行速度测试,随意一个php页面即可,这里是使用之前安装的phpmyadmin,200并发1000次请求,
这里采用PHP的版本是5.6,不过为了演示,事先将其关闭了opcache。
ab -c 200 -n 1000 http://192.168.139.135/pma/
开启opcache对opcode进行加速。
秒请求数从54.44到119.45近乎一倍的提升。显然opcode缓存对PHP的加速效果是十分可观的。
二、MySQL
2.1概念
数据库主要是表明如何组织数据的。有着三种主流的组织模型:层次模型(树状模型)、网状模型、关系模型
层次模型:一个主节点有多个子节点,一个子节点只有一个主节点,并不能让一个子节点拥有多个主节点。
网状模型:在层次模型的基础上进行改进,能够让一个子节点拥有多个主节点
关系模型:在网状模型上更进一步,解决了网状模型与应用程序的耦合性问题(应用程序发生改变底层数据库也随之改变;底层数据库发生改变应用程序也得发生改变)。
关系型数据表现为二维表结构,由行和列(row、column)构成,某列某行表示某单位。
关系型数据的设计理论,必须满足六个范式和五个约束。范式之间递次规范,即每个范式都是在前一个范式的基础下进一步规范,不同类型数据库所遵循的设计范式可能有些许区别;约束为数据库的硬性要求,数据库的基本要求,简单的来说,既是所填的数据必须在一定的范围里,不同类型数据库同样遵循不同约束。
设计范式是在设计期需满足的基本约束,约束是数据库设计完成之后对每个表的自我约束。
凡是应用程序根据设计范式实现,皆被称为数据库管理系统(DBMS),关系型数据库称为RDBMS
在范式的规范下能够尽可能的降低数据冗余,更重要的是需要修改时能够一次性地修改多个数据。
第一范式(1NF):无重复域。所有的域都是原子性的,即数据表中每一列都是不可再分割的。
第二范式(2NF):第一范式基础上,一个或多个字段能唯一标识实体,属性完全依赖主键。唯一标识是说,至少有一字段能标识其在表中的位置,换言之,没有完全一样的行。完全依赖的意思是不能存在仅依赖主键的一部分。如果存在那么主键必须单独分离出一个新的实体且建立新表来存储各个实体的唯一标识,新实体与实体之间为一对多关系。
第三范式(3NF):第二范式基础上,任何非主属性不依赖其他非主属性,第二表中依赖第一表时,若出现与第一表中相同的字段,则第二表的相同部分的字段必须为主键,表与表之前,新表主键能依赖旧表非主主键,相反,新表非主键不能依赖旧表非主主键。
除了这三个范式之外还有歌德巴斯范式、第四范式、第五范式(完美范式),范式越规范数据冗余越小,同样开发难度也越大。所以,一般而言满足前三种设计范式即可。
题外话,成也范式,败也范式。有一点不可否认的是,由于数据库设计需遵循设计范式,一张大的表也就必须拆分成无数张小表,这样一来完整的表扫描会给内存及CPU带来极大的压力(不过数据库本身便是为了避免全表扫描而设计的)——论优秀DBA的重要性。
现在数据库已经完成设计,之后便是数据库创建的多种约束。
六大自我约束(constraint):向数据表中提供要遵守的限制
主键约束:一个或多个字段的组合,填入的数据必须能在表中唯一标志本行;不能为空,即NOT NULL,一个表只能存在一个
唯一键约束:一个或多个字段的组合,填入的数据必须能在表中唯一标志本行;能为空,即NULL,一个表能存在多个
外键约束:一个表中某字段可填入数据取决于另一表的主键的数据
检查性约束:自我定义的表达式,只有满足该式才会被写入
非空约束:字段不能为空NOT NULL
默认约束:当填入的数值为空时,自动提供值
MySQL是关系型数据库管理系统的一种开源实现方式。所谓关系型数据库管理系统这里便不多阐述,简而言之便是将原始数据库中字段抽取出来,重新存储为新的数据库且其值当中包含指向数据块的键。
RDBMS:
MySQL:Mysql,MariaDB,Percona-Server
PostgreSQL:简称为pgsql --> EnterpriseDB
Oracle
MSSQL
2.2架构
mysql组建:
mysql能够自我分析、进行优化重新,重新书写最优的语句。锁管理系统完成多个程序之间的协作,读锁(独立)和写锁(共享)。事务管理器,为了保证事物的进行,会将事物保存在磁盘上两次,一为事物,二才是存储。恢复管理器,便是将只存储在事物日志的文件,恢复到原始文件中。
事物:多个操作被当作一个整体对待(ACID原则)。数据库要进行数据交换之时,事先在一段连续的磁盘空间中写入事物信息,双方要嘛是未修改的状态,要嘛是修改后的状态,只要有一方不一致便将回滚。
ACID:
1)原子性(atomic)
2)一致性(Consistency)
3)隔离性(Isolation)
4)持久性(Durability)
用户通过数据存储协议与SQL组建进行交互(每一款数据库所使用的协议皆不同),该协议是一种C/S架构的协议。监听3306号端口,用户为客户端(Client),SQL为服务器端(Server)
其中Client端有两种交互方式:1)通过程序接口:CLI接口和GUI接口;2)应用编程接口:Open DateBase Connection
三、小结
从概念简单地说起了PHP,讲到了PHP的Zend Engine和opcode,再介绍了PHP的加速器,以及最后演示了PHP内部Opcache加速Opcode的效果(5.5+)。紧接着便是Mysql,依旧是从简单的概念说起,Mysql仅是关系型数据库的一小部分,重点说了数据库的设计范式,五大基本约束。最后说到了数据库组建,数据库并非一个单独程序,而是由数个程序联合而成的小型系统。