• 第五十八篇 epoll模型、数据库


    一、IO模型回顾

    为了解决IO操作导致CPU闲置的问题

    1.阻塞模型

    执行recv或accept时,如果数据没到达,就阻塞当前程序,并让出CPU,让其去执行其他任务

    2.非阻塞模型

    1.将recv、accept、send 都设置成了非阻塞

    2.非阻塞情况下,没有数据会立马抛出异常,我们可以捕捉异常,然后切换到其他任务

    3.缺点:如果一直没有数据,程序将一直做无意义的循环,浪费CPU资源

    4.优势:单线程内并发可以处理多个客户端

    3.多路复用

    使用select来帮助我们检测socket的状态

    4.异步IO模型

    整个过程都是异步,包括wait_data和copy_data两个步骤

    5.信号驱动IO模型

    二、epoll模型

    1.select 的问题:

    1.当进程被唤醒,但它不清楚到底哪个socket有数据,因此只能遍历一遍存放进程的队列

    2.每一次select的执行,都需要将这些进程加入到等待队列中

    3.为了防止重复添加等待队列,当某一次操作完成时,也必须从等待队列中删除进程,所以select最大限制被设置为了1024,如此看来select连多线程都比不上

    4.于是推出了poll 和epoll,而poll只是简单对select进行了优化,但是还不够完美 ,epoll才是最后的解决方案

    **5.注意:epoll仅能在linux中使用 **

    2.epoll解决的问题

    1.避免频繁的对等待队列进行操作

    2.避免遍历所有socket

    3.epoll相关函数

    import select 导入select模块
    
    epoll = select.epoll() 创建一个epoll对象
    
    epoll.register(文件句柄,事件类型) 注册要监控的文件句柄和事件
    
    事件类型:
    
      select.EPOLLIN    可读事件
    
      select.EPOLLOUT   可写事件
    
      select.EPOLLERR   错误事件
    
      select.EPOLLHUP   客户端断开事件
    
    epoll.unregister(文件句柄)   销毁文件句柄
    
    epoll.poll(timeout)  当文件句柄发生变化,则会以列表的形式主动报告给用户进程,timeout
    
                         为超时时间,默认为-1,即一直等待直到文件句柄发生变化,如果指定为1
    
                         那么epoll每1秒汇报一次当前文件句柄的变化情况,如果无变化则返回空
    
    epoll.fileno() 返回epoll的控制文件描述符(Return the epoll control file descriptor)
    
    epoll.modfiy(fineno,event) fineno为文件描述符 event为事件类型  作用是修改文件描述符所对应的事件
    
    epoll.fromfd(fileno) 从1个指定的文件描述符创建1个epoll对象
    
    epoll.close()   关闭epoll对象的控制文件描述符
    

    4.举例

    1.服务端

    # coding:utf-8
    import socket, select
    
    server = socket.socket()
    server.bind(("127.0.0.1", 1688))
    server.listen(5)
    
    msgs = []
    
    
    fd_socket = {server.fileno(): server}
    epoll = select.epoll()
    # 注册服务器的 写就绪
    epoll.register(server.fileno(), select.EPOLLIN)
    
    while True:
        for fd, event in epoll.poll():
            sock = fd_socket[fd]
            print(fd, event)
            # 返回的是文件描述符 需要获取对应socket
            if sock == server:  # 如果是服务器 就接受请求
                client, addr = server.accept()
                # 注册客户端写就绪
                epoll.register(client.fileno(), select.EPOLLIN)
                # 添加对应关系
                fd_socket[client.fileno()] = client
    
            # 读就绪
            elif event == select.EPOLLIN:
                data = sock.recv(2018)
                if not data:
                    # 注销事件
                    epoll.unregister(fd)
                    # 关闭socket
                    sock.close()
                    # 删除socket对应关系
                    del fd_socket[fd]
                    print(" somebody fuck out...")
                    continue
    
                print(data.decode("utf-8"))
                # 读完数据 需要把数据发回去所以接下来更改为写就绪=事件
                epoll.modify(fd, select.EPOLLOUT)
                #记录数据
                msgs.append((sock,data.upper()))
            elif event == select.EPOLLOUT:
                for item in msgs[:]:
                    if item[0] == sock:
                        sock.send(item[1])
                        msgs.remove(item)
                # 切换关注事件为写就绪
                epoll.modify(fd,select.EPOLLIN)
    
    

    2.客户端

    
    #coding:utf-8
    #客户端
    #创建客户端socket对象
    import socket
    clientsocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    #服务端IP地址和端口号元组
    server_address = ('127.0.0.1',1688)
    #客户端连接指定的IP地址和端口号
    clientsocket.connect(server_address)
    
    while True:
        #输入数据
        data = raw_input('please input:')
        if data == "q":
            break
        if not data:
          continue
        #客户端发送数据
        clientsocket.send(data.encode("utf-8"))
        #客户端接收数据
        server_data = clientsocket.recv(1024)
        print ('客户端收到的数据:',server_data)
    #关闭客户端socket
    clientsocket.close()
    

    三、数据库

    1.数据库是什么

    1.存放数据的仓库

    2.存放数据的其他容器:列表、字典...实在内存中。优点:速度快;缺点:断电丢失

    3.文件存储。优点:永久保存;缺点:速度慢

    4.数据库的本质:基于CS架构(客户端/服务端)的程序,最终会将数据存储在服务端的磁盘上

    2.为什么使用数据库

    1.解决直接使用文件存储带来的问题

    2.文件存储的问题:

    • 1.速度慢

    • 2.由于单台机器性能肯定有上限,通过数据库联网的特性,可以用多个机器共同完成数据存储和操作的任务,如果是将数据以文件的形式分布在不同的机器上,处理起来则会比较麻烦,效率低

    • 3.不方便用户权限管理

    • **4.多个客户端并发访问,数据很难保证安全 ****

    3.服务器架构:

    • 1.分布式:每个服务器提供不同的服务(有时候某个业务流程也可能会涉及到多个服务器)

      • 1.优点: 耦合度降低 易维护

      • **2.缺点:通讯繁琐,容灾性没有集群好 **

    • 2.集群:所有服务器提供的服务是一模一样的

      • 优点:容灾性强,易扩展,可插拔

    通过网络 访问

    3.数据库的分类

    1.关系型数据库

    1.数据之间可以存在关联关系,关系型数据库会帮我们维护这种关系

    2.通常存储介质都是磁盘

    3.常见的关系型型数据库:

    # mysql      
    是我们学习的重点,是目前最流行的关系型数据库,因为其免费开源,性能不错 
    目前已经被oracle收购了,适用于中小型企业 
    
    # sqlserver	
    是微软推出的, 因为其只能运行在windows平台所以发展不咋地 
    
    # oracle
    目前最强大的关系型数据库,主要是在集群,和用户管理上,非常适合大型企业 
    
    # db2
    IBM的产品,主要面向企业级用户,不差钱的用户 捆绑硬件销售 
    

    2.非关系型数据库

    1.一般不帮我们维护数据之间的关系

    **2.通常存储介质都是内存 **

    3.常见的非关系型:

    mongoDB
    
    redis
    
    memcache   
    

    4.数据库的重要概念

    1.字段/具体数据(Column:列):文件中的某个字符串,比如,姓名:King

    2.记录(Row:行):文件中的某一行,比如,姓名:King,年龄:26,性别:male

    3.表(Table):某个文件。库下面有多个文件,比如,mysql文件夹中的user.MYD文件。这些文件中存放着多行记录

    4.库(DataBase):某个文件夹。数据库软件中有多个文件夹,比如,mysql文件夹

    5.DBMS:数据库管理系统(就是数据库软件,比如:mysql-5.6.43-winx64)

    **6.数据库服务器:运行DBMS的计算机(在电脑上搜索“服务”)

    5.数据库的安装和简单使用

    1.bin中存储所有执行文件(mysqld.exe是服务端,mysql.exe是客户端)

    2.data中存储数据:文件夹(库)--文件(表)

    3.运行客户端时,如果直接双击运行是进入游客模式,正确的运行方式是,在终端里指定用户名密码等参数:

    -h        主机名称 如果是本机 可以忽略
    
    -P(大写)   指定端口 默认3306  可以不写  
    
    -u        指定用户名   
    
    -p(小写)   指定密码
    
    
    # -h127.0.0.1 -P3306 -uroot -p
    

    4.添加环境变量:

    1.将bin的路径复制到系统环境变量中
    
    2.通过cmd管理员权限:注册系统服务,cmd中输入 mysqld  --install 
    

    5.一些简单操作:

    # cmd中输入
    
    1.如果之前装过mysql,想卸载:sc delete mysql(注意:mysql是服务名称不是文件名称)
    
    2.启动服务 net start mysql;
    
    3.停止服务 net stop mysql;
    
    4.查找某个进程 tasklist | findstr mysqld 
    
    5.杀死进程 taskkill /f /pid    111111
    

    6.mysql 5.6管理员密码的设置

    1.知道原始密码

    • 1.1登录到mysql 执行更新语句来修改:
    # 在MySQL下写SQL语句,注意末尾加分号
    
    1.先use mysql之后;
    2.再输入 update user  set password = password("123") where host="localhost" and  user="root";
    
    3.刷新全新 flush privileges;   
    3.或者重启mysqld;() 
    
    • 2.2 mysqladmin小工具:
    # 在cmd中输入不需要加分号
    
    1.mysqladmin -uroot -p123 password 321
    
    2.注意:-p是原始密码   
    

    **2.不知道原始密码 **

    • 2.1删除权限相关的文件 (容易挨打)

    • 2.2 跳过授权表:

    # 1.手动启动mysqld 指定参数   
    在cmd中输入  mysqld --skip-grant-tables
    
    # 2.开启一个客户端
    在mysql中输入 use mysql;
    再输入update user  set password = password("111") where host="localhost" and  user="root";
    
    # 3.重启mysqld 即可 
    

    7.库和表的增删改查

    1.数据必须存在表(文件)中,表必须存在库(文件夹)中

    1.库的操作

    • 1.不区分大小写
    • 2.不要使用关键字 例如create select 等.....
    • 3.不能使用纯数字
    • 4.可以下滑线 通常字符下滑线数字的组合
    # 均在MySQL中输入SQL语句(注意加分号)
    
    # 1.切换数据库(可以在库中切换到其他库)
    use 数据库名称(可以不加分号)
    
    # 2.增加库
    create database 数据库名称 charset urf8   /*创建库*/;
    
    # 3.查看所有数据库
    show databases   #查看有哪些库;
    
    # 4.查看数据客详细信息
    show create database 数据库名称  -- 查看mydb库的详细信息;
    
    # 5.删除数据库
    drop database 数据库名称
    
    
    
    # 6.修改数据库编码  可以进入到数据库文件夹中修改db.opt  
    #  第一行是编码 第二行是排序规则 自己搜索一个
    
    # 7.修改数据库名 可以直接修改对应的文件夹名称 
    

    2.表的操作

    # 1.查看当前库下的所有表
    show tables  -- 需要先 use 库名 之后;
    
    # 2.查看单个表的结构(内容)
    desc 表名称;
    
    # 3.查看表的创建语句(如何写的,我们要注意的规范)
    show create table 表名称;
    
    # 4.创建表(注意列的数据类型有char、text、int...但是没有str/string类型)
    create table 表名称(列名称1 列1的数据类型, 列名称2 列2的数据类型,...) charset gbk;
    
    # 5.修改表的名称
    rename table 旧名称 to 新名称;
    
    # 6.修改表的编码
    alter table 表名 charset utf8 -- 注意:在MySQL中只能写'utf8',别写‘utf-8'; 
    
    # 7.删除表
    drop table 名称;
    
    # 8.修改表的结构(内容)
    ## 8.1 添加字段(列)
    alter table 表名 add 列名 数据类型:
    ## 8.2 删除字段(列)
    alter table 表名 drop 列名:
    ## 8.3 修改字段(列)的数据类型
    alter table 表名 modify 列名 新的数据类型:
    ## 8.4 修改字段(列)名、数据类型
    alter table 表名 change 旧列名 新列名 新数据类型:
    
    # 9.清空表数据
    truncate table 表名;
    

    3.注释

    # 1.#注释内容
    show databases #注释内容;
    
    # 2.-- 注释内容(注意--后面必须空一格)
    show databases -- 注释内容;
    
    # 3./*注释内容*/
    show databases /*注释内容*/;
    
  • 相关阅读:
    国产化硬件设备性能追踪
    遇到的 超时重传
    系统加载
    nginx 全景图 转载
    引擎国产化适配&重构笔记
    记录一次syn后只收到ack的情况 --timewait
    PCIe网卡查看工具
    短说 反向代理&透传代理如何关闭connect
    XDP/AF_XDP ? eBPF
    ipvs--eBPF转载
  • 原文地址:https://www.cnblogs.com/itboy-newking/p/11185368.html
Copyright © 2020-2023  润新知