redis学习总结

旧街凉风 提交于 2020-03-05 10:49:42
  • 什么是redis
    redis是一个nosql(not only sql不仅仅只有sql)数据库.翻译成中文叫做非关系型型数据库.
    关系型数据库:以二维表形式存储数据
    非关系型数据库: 以键值对形式存储数据(key, value形式)
    是一家意大利的创业公司出的,然后后来这家公司被VMware赞助. redis底层用C语句编写.
   
    redis是将数据存放到内存中,由于内容存取速度快所以redis被广泛应用在互联网项目中,
    redis有点:存取速度快,官方称读取速度会达到30万次每秒,写速度在10万次每秒最有,具体限制于硬件.
    缺点:对持久化支持不够良好,
    所以redis一般不作为数据的主数据库存储,一般配合传统的关系型数据库使用.

  •  redis应用领域
    分布式缓存
    分布式session
    保存博客或者论坛的留言回复等.
    总之是用在数据量大,并发量高的情况下

  • 怎么用
    redis主要就是使用命令来进行操作,java端在代码中可以使用Jedis来操作redis服务器
    redis数据类型
        字符串String
        列表list  redis中使用的是双向循环链表来实现的list,在redis中更像栈
        散列Hash  一般应用于将redis作为分布式缓存,存储数据库中的数据对象
        集合set set中数据是无序的并且不允许重复
        有序集合zset redis会根据分数自动排序,这里可以使用在学生成绩排序,
            或者是手机应用商店流行软件排名等需求中
  • redis持久化方案:
    rdb:可以设置间隔多长时间全盘保存一次(Redis不用任何配置默认的持久化方案)
        有点:让redis的数据存取速度变快
        缺点:服务器断电时会丢失部分数据(数据的完整性得不到保证)
  • aof:可以设置实时保存 
        优点:持久化良好,能包装数据的完整性
        缺点:大大降低了redis系统的存取速度, 存储的文件占用内存高
  • 主从复制:    
    这里使用了心跳检测机制,主从复制必须使用rdb持久化方式
    从服务器一般是只读的,保证主服务器和从服务器的数据一致性

  • redis是单线程多路IO复用的一种非关系型数据库
  • redis的组队机制
使用 multi 和 exec 进行组队操作, 中间如果有一句执行错误, 则整个队列中的所有操作无效, 但是这个检查不能针对表面上一句没错的操作, 比如; set k1 v2 ; 这里的k1不是数字, 此时在队列中存在 incr k1 ; 则不会报错, 知道exec执行的时候除了这句话. 其他的语句全部执行成功. 也就是说出现了部分执行失败部分执行成功的问题, 这个问题相当于java的编译没错. 但是执行错了的情况这种错误光光使用multi和exec是无法避免的, multi和exec相当于编译检查无法检查运行错误所以不保证原子性
  • 悲观锁和乐观锁的问题探究
答: 悲观锁就是操作什么数据就给那个数据加锁, 应用场景是传统的关系型数据库使用悲观锁, 行锁和表锁, 他就是一个多疑的人, 什么事情都得加上锁才放心
乐观锁就是git或者svn, 借助版本的方式进行操作, 只有同一版本才能操作数据, 操作完数据后版本升级, 此时如果存在一个低版本的线程想要操作数据会被驳回, 线程会被结束, 另外新起一个线程再次读取新版本再去操作数据, 乐观锁就是谁先提交谁先升级版本号
redis就是使用的这种乐观锁机制

  • redis事务
  • 答: redis事务使用乐观锁机制
    利用watch key 对某个key设置版本号,对key的操作完毕后提高版本号
            解锁使用exec或者设置key的方式完毕锁, 或者放弃加锁并且不执行组队中的代码, 使用unwatch解除

    redis链接池的问题, 一般连接池在使用的时候都要先测试下, 因为连接池不知道连接是否失败, 而失败的原因是这个连接是redis给的, redis发现这个连接很久没人操作, 可能会收回连接, 所以每次借连接需要测试下是否可用(连接回收机制普遍存在, mysql也有)

    • 秒杀问题: 
    使用lua脚本解决秒杀乐观锁剩余问题, 秒杀情况下, 200个并发量300抢完后剩余100多的原因就是乐观锁问题, 版本不对, 驳回并且结束线程, 再起新的线程继续读取. 这个过程并发量高的同一个版本的线程无法进过乐观锁而结束, 直到剩余的线程小于数量剩余, 但是使用lua脚本的话, 不会出现那个问题了, 因为redis是单线程的. 使用lua脚本提交给redis的话. 这个lua脚本是由redis执行的, 不会出现并发问题, lua脚本都在redis内部执行的
    但是如果我们的redis是做集群的话, 则lua脚本将无法在redis中运行了, 而且版本在2.6以下的话, lua脚本将无法执行

    save手动存盘, 但是有问题, save占用主进程的存盘, 而后面的操作全部阻塞

    aof和rdb缓存同时存在, 这个时候听从aof的, 因为aof记载的详细

    aof记载详细, 但是速度慢且占用空间大, 所以创作者也给了优化, 重写aof文件

    主从复制优点
        读写分离, 性能扩展
        容灾快速恢复

    配置主从复制的过程
        1. 拷贝多个配置文件
        2. 开启daemon yes
        3. pid文件名称
        4.指定端口
        5. log文件名称
        6. dump.rdb名称
        7. aof配置文件
    这是配置主从复制的
        8. 从机配置slaveof ip port 这个配从不配主
    这是配集群的
        8. cluster-enabled yes 打开集群模式
        9. cluster-config-file nodes-6379.conf 设定节点配置文件名
        10.cluster-node-timeout 15000 配置节点失联时间, 超过则集群自动切换主从
    一主二仆模式

    正常一主二仆模式, 主机需要分发同步数据, 一次发送给两台机子, 压力大, 所以还有一种优化模式, 改成串联模式
    一仆人组长认一主人, 一仆人认一仆人组长,  语文老师和语文课代表和语文组长的关系这样就改成串联模式了
    仆人就是不能写, 只有主机才能写
    当主机宕机了, 从机使用 slaveof no one 设置成主机master

    使用哨兵模式监控主机是否宕机, 如果宕机则在剩下的从机中选举新的主机

    哨兵配置方式, 新加一个xxx.conf. 里面内容是 sentinel monitor mymaster ip port 1
    则上面的 1 代表着有几个哨兵觉得主机宕机了, 就切换主机的阈值 2 代表两台哨兵觉得主机挂了, 就重新选举主机

    主机故障选择从机的方式有三种
    1. 选择优先级最高的一种
    2. 选择偏移量最大的那个(得到数据量最多的那个)
    3. 选择runid最小的那个从机
    新主登基, 群仆俯手 旧主俯首
    上面这种情况的话, 通常java改用哨兵池的方式去获取主机了
    cluster nodes 指令查看集群主从
    ./redis-trib.rb create --replicas 1 192.168.25.189:6379 192.168.25.189:6380 192.168.25.189:6381 192.168.25.189:6389 192.168.25.189:6390 192.168.25.189:6391
     --replicas 1 代表给每一个主机配置一个从机
    集群中至少得有3台主机

    slots 槽, 有16384个槽, 这个原理和hash桶差不多

    mset在集群后不能用了, 只能通过在key后面加个{}写上英文, 就能跳到对应的槽
    集群中不需要哨兵也能进行选举, 只要个数过半就行, 集群自己管理自己, 不再需要哨兵

    如果一个集群的主从节点都挂掉了, 可以选择配置这个设置
    cluster-require-full-coverage yes , 不过默认不开启该功能, 配置了该功能为no, 即使slots槽中间空了一段也能继续存储

    集群的好处
        实现扩展
        分摊压力
        无中心配置相对简单
    集群缺点
        多键操作是不被支持的
        多键的redis事务不被支持的
        lua脚本不被支持


















    易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
    该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!