Blog

  • centos刷缓存

    Writing to this will cause the kernel to drop clean caches, as well as
    reclaimable slab objects like dentries and inodes. Once dropped, their
    memory becomes free.

    To free pagecache:
    回收页缓存

    echo 1 > /proc/sys/vm/drop_caches

    To free reclaimable slab objects (includes dentries and inodes):
    释放可回收的 slab 对象(包括目录和 inode)

    echo 2 > /proc/sys/vm/drop_caches

    To free slab objects and pagecache:

    echo 3 > /proc/sys/vm/drop_caches

    [root@node2 ~]# free -m
                  total        used        free      shared  buff/cache   available
    Mem:          48025       27055       12938         838        8031       19708
    Swap:         32767         280       32487
    [root@node2 ~]# echo "3" > /proc/sys/vm/drop_caches
    [root@node2 ~]# free -m
                  total        used        free      shared  buff/cache   available
    Mem:          48025       27052       20032         838         939       19778
    Swap:         32767         280       32487
    

    来源: setting-proc-sys-vm-drop-caches-to-clear-cache)

  • docker运行nginx

    Dockerfile

    FROM nginx
    RUN ["apt-get","update"]
    RUN ["apt-get","install","-y","vim"]
    # 以\ 与 && 符号连接命令,这样执行后,只会创建 1 层镜像.避免镜像膨胀过大
    RUN echo '这是一个本地构建的nginx镜像' > /usr/share/nginx/html/index.html \
            && echo '用来提供一个简单的文件下载功能' >> /usr/share/nginx/html/index.html \
            && mkdir -p /usr/local/nginx_down/ocotpus_http_download
    COPY ./server.conf /etc/nginx/conf.d/default.conf
    #定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷
    #通过 VOLUME 指令创建的挂载点,无法指定主机上对应的目录,是自动生成的
    VOLUME ["/usr/local/nginx_down/ocotpus_http_download/"]
    

    构建镜像

    docker build -t octopus_rpm_nginx .

    运行

    • 端口映射到本机8081
    • 映射了本机的目录/usr/local/nginx_down/ocotpus_http_download/
    • –rm 关闭容器时,删除容器
    docker run -d  -p 192.168.8.73:8081:80 \
    -v /usr/local/nginx_down/ocotpus_http_download/:/usr/local/nginx_down/ocotpus_http_download/ \
    --rm \
    --name rpmnginx  octopus_rpm_nginx
    
  • mysql调优带来的启示

    调优要抓住关键点.缓存也有缓存的弊端.如何让缓存价值更高.硬件层面解决问题.

    进行 mysql 管理优化,三大原则

    1. 访问内存数据的速度比访问磁盘数据速度快
    2. 将数据保存在内存里,尽可能减少磁盘活动
    3. 保留索引的信息比保留行的内容重要

    调优的基本方式

    1. 一次只改一个参数.如果同时修改多个变量,则很难对每个更改所产生的影响进行评估
    2. 逐步增大系统变量值.
      1. 避免一下子耗光系统资源
      2. 避免系统因为你将变量设置过高而变得异常快或者异常慢
    3. 不要在生成环境做测试
    4. 禁用不需要的存储引擎.减少内存使用.
    5. 保持简单的访问权限.在 MySQL 数据库中,权限表除了 user 表外,还有 db 表、tables_priv 表(对单个表进行权限设置)、columns_priv 表(对单个数据列进行权限设置)和 procs_priv 表(对存储过程和存储函数进行权限设置).当配置它们时,服务器在检查 sql 语句权限时,一定会检查它们的内容.

    一般调整的通用型系统变量

    1. back_log

      在处理当前连接时,排队等待连接的最大请求数.

    2. max_connections

      服务器支持的最大客户端并发连接数.可以使用show status查看变量Max_used_connections

    3. table_open_cache

      当服务器打开文件时,会试图将它们保持在打开状态,以减少必须要完成的文件打开操作和文件关闭操作的数量.可以通过show global status like 'Opened_tables'进行评估

      1. 如果Opened_tables迅速增大,则意味缓存太小
      2. 大一点的缓存可以减少缓存失效
    4. table_definition_cache

      与table_open_cache正相关,用于控制存储表定义的缓存大小.

    5. open_files_limit

      1. 考虑操作系统对进程所用使用的文件句柄限制
      2. mysql 本身也有自己的open_files_limit限制
    6. max_allowed_packet

      客户端通信的缓存区的最大值.默认 1MB ,允许的最大值为 1GB.可能还需要相应的增大 下面两个变量

    • read_buffer_size 读取操作使用的缓冲区大小
    • sort_buffer_size 排序操作使用的缓冲区大小

      每一个 session 都会受其影响,应该要逐步调整

    innodb 缓冲池

    基本组成

    1. 是个列表,并且分新旧两个子列表
    2. 改进的 LRU 策略,插入数据插入到旧的子列表前
      1. 如果数据块是查询需要的,会被访问后移到新子列表前面
      2. 如果是由于预读需要,可能不会被访问,减少了预读对缓存的影响

    一般调节的参数

    • innodb_buffer_pool_size

      缓冲池大小.单位为字节

    • innodb_buffer_pool_instance

      如果innodb_buffer_pool_size>=1GB && innodb_buffer_pool_instance>1,Innodb 会把缓冲池处理成多个小的缓冲池实例.通过随机分配的方式,减少并发竞争.

    • 影响缓冲池缓存失效的参数

      • innodb_old_blocks_pct 缓冲池的旧子列表所占的百分比.默认是 37.
      • innodb_old_blocks_time 一个缓存块在第一次访问之后,下次访问之前,需要在旧子列表待多少毫秒才移动到新子列表.(将其设置为大于 0,可以防止类似表扫描这种一次性访问大量数据的行为对缓冲池产生太大影响)

    考虑开启 mysql 查询缓存

    • select 语句执行后,服务器会记住这条查询语句的文本和它返回的结果
    • 查询缓存通过比较查询语句的文本进行比对,是否命中缓存
    • 查询返回的结果不确定则不会存储.例如使用时间 NOW()函数.
    • 表被修改,指向它的所有缓存查询都失效

    弊端

    • 为查询缓存分配过大的内存,会导致比较当前查询语句是否命中缓存花费过多时间.
    • 多客户端连接情况下,带来了并发的缓存竞争.(因为查询缓存只能单线程操作)

    硬件

    • 更多内存
    • 更强,更多处理器
    • 使用更快的硬盘
      • 全用 ssd
      • 利用机械盘组成 raid
      • 将磁盘活动分布到不同的物理设备上,充分利用并行特性
  • 为什么要索引

    为什么要索引

    没有索引查找数据要全表扫描

    索引如何起作用

    • 一种使用索引提高效率的方法:我们可以得知匹配行在什么地方结束,从而跳过其它部分
    • 另一种使用索引提高效率的方法:利用定位算法,不用从索引开始位置进行线性扫描,即可直接找到第一个匹配项(例如二分查找比扫描要快很多)。

    为什么不直接对数据排序

    如果一个表只有一个索引这样做事可以的,但是可能我们还想添加第二索引。例如用户表的id和名称字段。

    此外索引里的行通常比表里的数据行更短。当发生插入或者删除时,为保存排序顺序,来回移动较短的索引值,要比来回移动较长的数据行更加容易。

    索引如何影响mysql查询

    假设,你有3个表t1,t2,t3,其中每个表都包含一个列,它们分别为i1,i2,i3,并且每个表都有1000行记录。

    select t1.i1, t2.i2, t3.i3
    from t1 inner join t2 inner join t3
    where t1.i1 = t2.i2 and t2.i2 = t3.i3
    
    • 如果没有索引,需要尝试所有组合1000 * 1000 *1000

    • 如果i1,i2,i3都建有索引

      • 从表t1中选择第一个行,看该行包含的是什么值
      • 利用表2的索引,直接转到表t1的值相匹配的那个行。类似利用表t3的索引直接转到与表t1的值相匹配的那个行
      • 继续选择表t1的下一行,然后重复前面的过程。

      整个过程,只对表t1执行了全扫描操作。对表t2,t3执行的是索引查找。

    因此我们要

    1. 为用于搜索、排序或者分组的列(候选列)创建索引,而对于用作输出显示的列则不用创建索引。
      1. where
      2. order by and group by
    2. 认真考虑数据列基数(列能容纳的所有非重复值得个数)。

      基数越高,重复率越低,索引的使用效果越好。并且查询优化程序确定出某个值在表的行里出现频率很大时,它会跳过索引,转而执行全表扫描操作(因此性别列建索引没啥用)

    3. 索引短小值

      1. 数据类型越小,内存占用越小
      2. 索引的比较操作更快
      3. 键缓存的索引块可能容纳更多的键值
      4. 对于innodb 使用聚簇索引,数据行和主键值存储在一起。在二级索引里进行查找,会先得到主键值,再通过主键定位到相应的行。因此主键值会在一个二级索引里都会重复出现
    4. 索引字符串的前缀。

    5. 利用最左前缀。

      当创建包含n个列的复合索引时,实际上会创建n个专供mysql使用的索引。如果对一个表添加一个(country/state/city)的复合索引,那么索引会根据country/state/city的顺序来进行索引排序。因此country也是顺序的,可以直接使用country进行检索。

    6. 不要建立过多的索引

      1. 索引占用空间
      2. 表的修改需要对索引进行维护
    7. 让参与比较的索引保存匹配。
      1. 哈希散列,适合精确查找
      2. B树索引适合范围查询
    8. 利用慢查询日志找出那些性能低劣的查询

  • Innodb 逻辑存储结构

    Innodb 逻辑存储结构

    [TOC]

    来源

    《mysql技术内幕》

    从一条数据说起——InnoDB行存储数据结构

    MYSQL存储引擎INNODB详解,从底层看清INNODB数据结构

    22.2.1.1 Fil Header

    重要的

    • innodb B+树索引本身并不能找到具体的一条记录,能找到只是该记录所在的页。数据库把页载入到内存,然后通过page directory在进行二叉查找具体的记录。
    • 数据记录在页中是以堆的形式存放的
    • VARCHAR 或者 BLOB 对象大的时候,使用溢出页面存放实际的数据。

    (more…)