zoukankan      html  css  js  c++  java
  • DAY 105 redis集群搭建

    1 redis介绍和基本安装
    -celery+redis:消息存储,队列
       -去重,计数,缓存,geo,
       -性能很高
       -源码安装
       
    2 api
    -公共api
       -字符串
       -列表
       -hash
       -集合
       -有序集合
       
    3 客户端
    -python 的客户端:redis模块
       
    4 高级使用
    -慢查询
       -pipline,事务
       -发布订阅
       -bitmap
       -HyperLogLog
       -geo
    5 持久化
    -rdb:快照方式
       -aof:日志方式
       
    6 主从复制
    -一主一从
       -一主多从
       
    7 哨兵(高可用)

     

    1 redis集群搭建

    # 第一种:最原始,一步步做(基本不用)
    -启动多个节点(6个节点)
       -相互meet
       -指派槽
       -做主从
    # 第二种:ruby脚本

    # 第三种:新版本上,官方直接支持用命令实现
    -redis-cli --cluster(meet,分配槽,做主从)
       
       
    # 第三种:
    ###1 生成6个配置文件起6个节点,6个配置文件
    port 7000
    daemonize yes
    dir "/opt/soft/redis/data/"
    logfile "7000.log"
    dbfilename "dump-7000.rdb"
    cluster-enabled yes
    cluster-config-file nodes-7000.conf
    cluster-require-full-coverage yes

    sed 's/7000/7001/g' redis-7000.conf > redis-7001.conf
    sed 's/7000/7002/g' redis-7000.conf > redis-7002.conf
    sed 's/7000/7003/g' redis-7000.conf > redis-7003.conf
    sed 's/7000/7004/g' redis-7000.conf > redis-7004.conf
    sed 's/7000/7005/g' redis-7000.conf > redis-7005.conf


    ###2 启动6个节点
    ./src/redis-server ./redis-7000.conf
    ./src/redis-server ./redis-7001.conf
    ./src/redis-server ./redis-7002.conf
    ./src/redis-server ./redis-7003.conf
    ./src/redis-server ./redis-7004.conf
    ./src/redis-server ./redis-7005.conf

    ps -ef |grep redis
    # 现在往任意一个节点中写数据,都写不进去

    ###3 meet,分配槽,建立主从

    ##./src/redis-cli --cluster help 查看cluster命令的使用
    redis-cli --cluster create --cluster-replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
                           
    yes

    # 写入数据测试
    连接任意一个主节点:发现存需要去固定的节点存取
    所以我们使用(自动重定向到固定节点存取)
    ./src/redis-cli -a -p 7000

    1.1 扩容

    #配置文件
    sed 's/7000/7006/g' redis-7000.conf > redis-7006.conf
    sed 's/7000/7007/g' redis-7000.conf > redis-7007.conf

    #启动
    redis-server ./redis-7006.conf
    redis-server .redis-7007.conf

    # 让集群感知到新进来的
    redis-cli -p 7000 cluster meet 127.0.0.1 7006
    redis-cli -p 7000 cluster meet 127.0.0.1 7007

    #做主从
    redis-cli -p 7007 cluster replicate ca0a50decb2d75985599533471a1b49945db11dd

    # 迁移槽
    redis-cli --cluster reshard 127.0.0.1:7000
       -迁移多少
       -迁到谁(id)
       -all(均匀的从每个节点拿一些)
       -yes
       
    # 查看集群信息
    cluster nodes

    #测试

    缩容

    # 下线迁槽(把7006的1366个槽迁移到7000上)
    redis-cli --cluster reshard --cluster-from 7006的id --cluster-to 7000的id --cluster-slots 1366 127.0.0.1:7000
    yes

    redis-cli --cluster reshard --cluster-from 7006的id --cluster-to 7001的id --cluster-slots 1366 127.0.0.1:7001
    yes
    redis-cli --cluster reshard --cluster-from 7006的id --cluster-to 7002的id --cluster-slots 1365 127.0.0.1:7002
    yes

    # 忘记节点,关闭节点
    redis-cli --cluster del-node 127.0.0.1:7000 要下线的7007id  
    # 先下从,再下主,因为先下主会触发故障转移
    redis-cli --cluster del-node 127.0.0.1:7000 要下线的7006id


    # 关掉其中一个主,另一个从立马变成主顶上, 重启停止的主,发现变成了从

    2 缓存的优化和使用

    1 做缓存
    2 缓存更新策略
    -LRU -Least Recently Used,没有被使用时间最长的
    -LFU -Least Frequenty User,一定时间段内使用次数最少的
    -FIFO -First In First Out
       -LIRS (Low Inter-reference Recency Set)是一个页替换算法,相比于LRU(Least Recently Used)和很多其他的替换算法,LIRS具有较高的性能。这是通过使用两次访问同一页之间的距离(本距离指中间被访问了多少非重复块)作为一种尺度去动态地将访问页排序,从而去做一个替换的选择
       
       
    3 缓存穿透  缓存击穿 缓存雪崩
    ### 缓存穿透
    #描述:
    缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。
    #解决方案:
    1 接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;
    2 从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击
    3 通过布隆过滤器实现,避免缓存穿透



    ### 缓存击穿
    #描述:
    缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力
    #解决方案:
    设置热点数据永远不过期。


    ### 缓存雪崩
    #描述:
    缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是,        缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。
    # 解决方案:
    1 缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
    2 如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中。
    3 设置热点数据永远不过期。


    ##双写一致性
       1. 先更新数据库,再更新缓存
       2. 先删除缓存,再更新数据库
       3. 先更新数据库,再删除缓存(我们用的)

     

    3 mysql主从搭建

    1 写操作到主,读操作去从
    2 一台机器,使用docker搭建(配置文件)
    -

     

    4 django实现读写分离

    #1 基于docker
    sudo yum install -y yum-utils device-mapper-persistent-data lvm2
    sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    yum install docker-ce
    systemctl start docker  # 启动docker

    docker pull mysql:5.7   #拉取mysql5.7镜像
       
       
    # 2 修改配置文件
    ###主
    [mysqld]
    user=mysql
    character-set-server=utf8
    default_authentication_plugin=mysql_native_password
    secure_file_priv=/var/lib/mysql
    expire_logs_days=7
    sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
    max_connections=1000

    server-id=100
    log-bin=mysql-bin


    ###从
    [mysqld]
    user=mysql
    character-set-server=utf8
    default_authentication_plugin=mysql_native_password
    secure_file_priv=/var/lib/mysql
    expire_logs_days=7
    sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
    max_connections=1000

    server-id=101
    log-bin=mysql-slave-bin
    relay_log=edu-mysql-relay-bin


    ##3 启动容器,使用配置文件启动
    docker run  -di -v /home/mysql/data/:/var/lib/mysql -v /home/mysql/conf.d:/etc/mysql/conf.d -v /home/mysql/my.cnf:/etc/mysql/my.cnf -p 33307:3306 --name mysql-master -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
                       
                       
                       
    docker run  -di -v /home/mysql2/data/:/var/lib/mysql -v /home/mysql2/conf.d:/etc/mysql/conf.d -v /home/mysql2/my.cnf:/etc/mysql/my.cnf -p 33306:3306 --name mysql-slave -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7

                       
    ##4 远程连接从库,新建一个用户(test)
    #连接主库
    mysql -h 47.100.50.84 -P 33307 -u root -p123456
    #在主库创建用户并授权
    ##创建test用户
    create user 'test'@'%' identified by '123';
    ##授权用户
    grant all privileges on *.* to 'test'@'%' ;
    ###刷新权限
    flush privileges;
    #查看主服务器状态(显示如下图)
    show master status;

     

    ### 5 从库的配置

    #连接从库
    mysql -h 47.100.50.84 -P 33306 -u root -p123456
    #配置详解
    /*
    change master to
    master_host='MySQL主服务器IP地址',
    master_user='之前在MySQL主服务器上面创建的用户名'
    master_password='之前创建的密码',
    master_log_file='MySQL主服务器状态中的二进制文件名',
    master_log_pos='MySQL主服务器状态中的position值';
    */
    #命令如下
    change master to master_host='47.100.50.84',master_port=33307,master_user='test',master_password='123',master_log_file='mysql-bin.000003',master_log_pos=0;
    #启用从库
    start slave;
    #查看从库状态(如下图)
    show slave statusG;


    ### 6 测试主从
    #在主库上创建数据库test1,创建表,插入数据

     

    5 读写分离

    多数据库:
    python manage.py makemigraions

    python manage.py migrate app名称 --databse=配置文件数据名称的别名

    #手动操作:
       # 读(db1),写(default)分离
       res = models.Book.objects.all().using('db1')

       # 写到default中
       # models.Book.objects.using('default').create(name='西游记')

    #自动操作:
    ## 写一个py文件,新建一个类,如下
    class Router1:
       def db_for_read(self, model, **hints):

           return 'db1'

       def db_for_write(self, model, **hints):

           return 'default'
    ##在配置文件中配置
    DATABASE_ROUTERS = ['db_router.Router1',]
    ## 以后,自动的读写分离,不需要额外处理


    #粒度更细(指定读book表时,去db1库读)
    class Router1:
       def db_for_read(self, model, **hints):
           if model._meta.model_name == 'book':  # 通过表名限制更细粒度
               return 'db1'
           else:
               return 'default'

       def db_for_write(self, model, **hints):
           return 'default'

    补充

    1 你们项目的并发量
    -uwsgi+django  200以内
       -用户数:50w用户数
       -日活:1w
       -并发量:几百

     

  • 相关阅读:
    java的构造方法 java程序员
    No result defined for action cxd.action.QueryAction and result success java程序员
    大学毕业后拉开差距的真正原因 java程序员
    hibernate的回滚 java程序员
    验证码 getOutputStream() has already been called for this response异常的原因和解决方法 java程序员
    浅谈ssh(struts,spring,hibernate三大框架)整合的意义及其精髓 java程序员
    你平静的生活或许会在某个不可预见的时刻被彻底打碎 java程序员
    Spring配置文件中使用ref local与ref bean的区别. 在ApplicationResources.properties文件中,使用<ref bean>与<ref local>方法如下 java程序员
    poj1416Shredding Company
    poj1905Expanding Rods
  • 原文地址:https://www.cnblogs.com/DEJAVU888/p/14914407.html
Copyright © 2011-2022 走看看