学习

linux_韩老师_01-06

基础介绍 #

  • 本套课程内容
    • 基础篇: linux入门、vm和Linux的安装、linux目录结构
    • 实操篇
      • 远程登录(xshell,xftp)、实用指令、进程管理、用户管理
      • vi和vim编辑器、定时任务调度、RPM和YUM
      • 开机、重启和用户登录注销、磁盘分区及挂载、网络配置
  • linux使用的地方
    • 在linux下开发项目(需要把javaee项目部署到linux下运行)
    • linux运维工程师(服务器规划、优化、监控等)
    • linux嵌入式工程师(linux下驱动开发[c,c++])
  • linux应用领域
    • 个人桌面
    • 服务器(免费稳定高效)
    • 嵌入式领域(对软件裁剪,内核最小可达几百kb等)

linux介绍 #

  • linux是一个开源免费操作系统
  • linux吉祥物
    tux(/tu’ks/唾可si),没找到音标,将就一下
  • linux之父,linus,也是git的创作者
    主要发行版:Ubuntu、RedHat,Centos,Debian等
    RedHat和Centos使用同样的源码,但是RedHat收费
  • Linux和Unix的关系
    unix也是一个操作系统,贝尔实验室。做一个多用户分时操作系统, multics,但是没完成。其中一个后来在这基础上,完成的操作系统为unix (原本是B语言写的),后面和另一个人用unix用c语言改写了。
    unix源码是公开的,后面商业公司拿来包装做成自己的系统, 后面有个人提倡自由时代用户应该对源码享有读写权利而非垄断
    后面RichardStallman发起GNU计划(开源计划),Linus参加该计划,并共享出linux内核,于是大家在此基础上开发出各种软件。linux又称GNU/linux
  • Linux和Unix关系

VMWare安装Centos7.6 #

在windows中安装Linux系统

  • VM和Linux系统在pc中的关系

  • 安装过程中,网络模式使用NAT模式

  • 选择最小安装,且选择CompatibilityLibraries和DevelopmentTools

  • linux分区
    一般分为三个

    一般boot1G,swap分区一般跟内存大小一致,这里是2G,所以根分区就是剩下的,也就是20-1-2=17G
    如图,boot,/,swap都是标准分区。且boot和/是ext4的文件格式,swap是swap的文件格式

  • 修改主机名

  • 修改密码及增加除root外的普通用户

  • 修改网络为固定ip(NAT模式下)

    • 先在VM里面把子网ip改了,这里改成 192.168.200.0
    • 然后改网关为192.168.200.200
    • 使用yum install -y vim 安装文本编辑工具
    • 最后在linux中改配置文件
      vim /etc/sysconfig/network-scripts/ifcfg-ens33
      
    • 其中先修改BOOTPROTO=“static”
    • 然后设置ip地址、网关和DNS, 下面是添加到上面的ifcfg-ens33后面,不是直接执行代码
      IPADDR=192.168.200.200
      GATEWAY=192.168.200.2
      DNS1=192.168.200.2
      
    • 使用命令重启网络
      service network restart 
      # 或者直接重启电脑 reboot
      
  • 这里顺便装一下zsx

    ...

redis_尚硅谷_19-A

验证码模拟 #

  • 首先需要一个MyRedis单例类
/**
 * MyRedis单例类
 */
public class MyJedis {
    private static Jedis myJedis;

    public static Jedis getInstance() {
        //如果是空则进行初始化
        if (myJedis == null) {
            //由于synchronized同步是在条件判断内,所以同步
            //并不会一直都执行,增加了效率
            synchronized (MyJedis.class) {
                if (myJedis == null) {
                    //设置密码
                    DefaultJedisClientConfig.Builder builder = DefaultJedisClientConfig.builder()
                            .password("hello.lwm");
                    DefaultJedisClientConfig config = builder.build();

                    Jedis jedis = new redis.clients.jedis.Jedis("192.168.200.200", 6379, config);

                    return jedis;
                }
            }

        }
        return myJedis;
    }
}

redis_尚硅谷_18

Jedis操作Redis6 #

  • 插曲:本地项目关联github远程库
     git init
     git add README.md
     git commit -m "first commit"
     #-m表示强制重命名
     git branch -M main
     #使用别名
     git remote add origin git@github.com:lwmfjc/jedis_demo.git
     #用了-u之后以后可以直接用git push替代整行 
     git push -u origin main 
    
  • jedis pom依赖
    <!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>4.0.1</version>
    </dependency>
    
  • jedis使用
    public class Main {
        public static void main(String[] args) {
            //设置密码
            DefaultJedisClientConfig.Builder builder = 
            DefaultJedisClientConfig.builder()
                    .password("hello.lwm");
            DefaultJedisClientConfig config = builder.build();
    
            Jedis jedis = new Jedis("192.168.200.200", 6379, config);
            //ping
            String value = jedis.ping();
            System.out.println(value);
            //返回所有key
            Set<String> keys = jedis.keys("*");
            System.out.println("key count: " +
                    keys.size());
            for (String key : keys) {
                System.out.printf("key--:%s---value:%s\n", 
            key, jedis.get(key));
            }
    
            System.out.println("操作list");
            //操作list
            jedis.lpush("ly-list", "java", "c++", "css");
            List<String> lrange = jedis.lrange("ly-list", 0, -1);
            for (String v : lrange) {
                System.out.println("value:" + v);
            }
    
            //操作set
            System.out.println("操作set");
            jedis.sadd("ly-set", "1", "3", "3",
                    "5", "1");
            Set<String> smembers = jedis.smembers("ly-set");
            for (String v : smembers) {
                System.out.println("value:" + v);
            }
            //操作hash
            System.out.println("操作hash");
            jedis.hset("ly-hash", "name", "lidian");
            jedis.hset("ly-hash", "age", "30");
            jedis.hset("ly-hash", "sex", "man");
            Map<String, String> lyHash = jedis.hgetAll("ly-hash");
            for (String key : lyHash.keySet()) {
                System.out.println(key + ":" + lyHash.get(key));
            }
            //操作zset
            System.out.println("操作zset");
            jedis.zadd("person", 100, "xiaohong");
            jedis.zadd("person", 80, "xiaoli");
            jedis.zadd("person", 90, "xiaochen");
            List<String> person = jedis.zrange("person", 0, -1);
            for (String name : person) {
                System.out.println(name);
            }
            //结束操作
            jedis.flushDB();
            jedis.close();
        }
    }
    

redis_尚硅谷_12-17

Redis配置文件 #

  • redis中单位的设置,支持k,kb,m,mb,g,gb,且不区分大小写
  • include (包含其他文件,比如公共部分)
  • bind
    bind 127.0.0.1 ::1 #listens on loopback IPv4 and IPv6 
    
    • 后面这个::1,相当于ipv6版的127.0.0.1。在redis配置文件中,整句表示只允许本地网卡的某个ip连接(但是它并不能指定某个主机连接到redis中。比如本机有两个网卡,两个ip,可以限定只有其中一个ip可以连接)
    • 如果注释掉了/或者bind 0.0.0.0,表示允许所有主机连接
  • protected-mode
    protected-mode yes 
    
    • 设置保护模式为yes,protected是redis本身的一个安全层,这个安全层在同时满足下面三个条件的时候会开启,开启后只有本机可以访问redis
      • protected-mode yes
      • 没有bind指令(bind 0.0.0.0不属于这个条件)
      • 没有设置密码 (没有设置requirepass password)
    • 只要上面一个条件不满足,就不会开启保护模式。换言之,只要设置了bind 0.0.0.0或者没有设置bind,且不满足上面三个条件之一,就能够进行远程访问(当然,linux/windows的6379端口要开放)
  • tcp-backlog 表示未连接队列总和
  • timeout 秒为单位,时间内没操作则断开连接
  • tcp-keepalive 300 心跳检测,每隔300s检测连接是否存在
  • pidfile /var/run/redis_6379.pid 将进程号保存到文件中
  • loglevel 表示日志的级别/debug/verbose/notice/warning
  • logfile "" 设置日志的路径
  • database 16 默认有16个库
  • requirepass password 设置密码
  • maxclients 设置最大连接数
  • maxmemory 设置最大内存量,达到则会根据移除策略进行移除操作

Redis的发布和订阅 #

  • 发布订阅,pub/sub,是一种消息通信模式:发送者pub发送消息,订阅器sub接收消息
  • 发布者能发布消息,订阅者可以订阅/接收消息
  • 操作
    subscribe channel1 #客户端A订阅频道 
    
    publish channel1 helloly #向频道发送消息
    
    此时订阅channel1频道的客户端就会接收到消息

redis新数据类型 #

Bitmaps #

  • 进行二进制操作

    ...

redis_尚硅谷_06-11

Redis针对key的基本操作 #

  • 常用命令
    keys * #查找当前库所有库
    exists key1 #key1是否存在 1存在;0不存在
    type key2 #key2的类型
    del key3 #删除key3
    unlink key3 #删除key3(选择非阻塞删除。会先从元数据删除,而真正删除是异步删除)
    expire key1 10 #设置key1的过期时间,单位秒
    ttl key1 #获取key1的剩余存活时间,-2表示key已过期或不存在,-1表示永不过期
    select 1 #切换到1号库(redis中有15个库,默认在库1)
    dbsize #查找当前redis库中有多少个key
    flushdb #清空当前库
    flushall #清空所有库
    

Redis中常用数据类型 #

字符串(String) #

  • String是二进制安全的,可以包含jpg图片或序列化的对象
  • 一个Redis中字符串value最多可以只能是512M
  • 常用命令
    set key1 value1
    get key1 
    set key1 value11 #将覆盖上一个值
    append key1 abc #在key1的值追加"abc"
    strlen key1 #key值的长度
    setnx key1 value #当key不存在时才设置key
    incr n1 #将n1的值加一,,如果n1不存在则会创建key n1 并改为1(0+1)
    decr n1 #将n1的值减一,如果n1不存在则会创建key n1 并改为-1(0-1)
    incrby n1 20 #将n1的值加20,其他同上
    decrby n1 20 #将n1的值减20,其他同上
    
  • redis原子性
    incr具有原子性操作
    java中的i++不是原子操作
  • 其他命令
    mset k1 v1 k2 v2
    mget k1 k2 
    msetnx k1 v1 k2 v2 #仅当所有的key都不存在时才会进行设置
    getrange name 0 3 #截断字符串[0,3]
    setrange name 3 123 #从下标[3]开始替换字符串(换成123)
    setex k1 20 v1 #设置过期时间为20s
    expire k1 30 #设置过期时间为30s
    getset k1 123 #获取旧值,并设置一个新值
    
  • 数据结构,SimpleDynamicString,SDS,简单动态字符串,内部结构类似Java的ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配

列表 (List) #

  • 单键多值
  • 底层是双向链表
  • 从左放
    lpush k1 v1 v2 v3 #从左边放(从左往右推)
    lrange k1 0 -1 #从左边取(v3 v2 v1)
    
  • lpush:
  • 从右放
    rpush k2 v1 v2 v3 
    
  • brpush:
  • lpop/rpop
    lpop k2 #从左边弹出一个值
    lpop k2 2 #从左边弹出两个值,当键没有包含值时,键被删除
    
  • rpoplpush
    lpush a a1 a2 a3
    rpush b b1 b2 b3
    rpoplpush a b #此时a:a1 a2,b:a3 b1 b2 b3
    
  • lrange
    lrange b 1 2 #获取b中下标[1,2]的所有值
    lrange b 1 -1 #获取所有值[1,最大下标]的所有值
    
  • lindex,llen
    lindex b 1 #直接取第一个下标的元素
    llen b #获取列表的长度
    
  • linsert
    linsert b before b2 myinsert
    linsert b after b2 myinsert
    #在某个列表的值(如果重复取第一个)的位置之前/之后插入值
    
  • lrem,lset
    lrem b 2 a #从b列表中,删除两个a(从左往右)
    lset b 2 AA #把下标2的值设置为AA
    
  • list数据结构是一个快速列表,quicklist
    当元素较少的时候,会使用连续的内存存储,结构时ziplist,即压缩列表;当数据多的时候会有多个压缩列表,然后会链接到一起(使用双向指针)

集合(Set) #

  • 特点:无序,不重复
  • Set:string类型的无序集合,底层是一个value为null的hash表;添加/删除时间复杂度为O(1)
  • 常用命令
    sadd k1 v1 v2 v3 v2 v2 v1 #设置集合中的值
    smembers k1 #取出集合中的值
    sismember k1 v3 #k1是否存在v3,存在返回1,不存在返回0
    scard k1 #返回集合中元素的个数
    srem k1 v2 v3 #删除集合中的v2和v3
    spop k1 #从k1中随机取出一个值
    srandmember k1 2 #从k1中随机取出2个值
    
    smove a k a1 #从a中将a1移动到k中
    sinter a k #取a,k的交集
    sunion a k #取a,k的并集
    sdiff a k #返回两个集合的差集(从集合a中,去除存在集合k中的元素,即a-k)
    
  • Set数据结构时dict字典,字典使用哈希表实现的

哈希(Hash) #

  • 是String类型的field和value的映射表,用来存储对象,类似java中的Map<String,Object>
  • 常用命令
    hset user:1001 id 1 #设置(对象)user:1001的id属性值
    hset user:1001 name zhangsan 
    hget user:1001 name #取出user:1001的name
    hmset user:1001 id 1 name zhangsan #批量设置(现在hset也可以批量设置了,hmset已弃用)
    hexists user:1001 id 1 #判断属性id是否存在
    hkeys user:1001 #查看hash结构中的所有filed
    hvals user:1001 #查看hash结构中所有value
    hincrby user:1001 age 2 #给hash结构的age属性值加2
    hsetnx user:1001 age 10 #给hash结构的age属性设置值为10(如果age属性不存在)
    
  • hash类型数据结构,当field-value长度较短时用的是ziplist,否则使用的是hashtable

有序集合(ZSet) #

  • 与set很相似,但是是有序的
  • 有序集合的所有元素(成员)都关联一个评分(score),score用来从最低到最高方式进行排序,成员唯一但评分是重复的
  • 常用命令
    zadd topn 100 xiaoming 120 xiaohong 60 xiaochen #添加key并为每个成员添加评分
    zadd topn xiaoli 200 
    zrange topn 0 -1 #查找出所有成员(按排名由小到大)
    zrange topn 0 -1 withscores #从小到大查找所有成员并显示分数
    zrangebyscore topn 130 200 #查找所有在130-200的成员
    zrevrangebyscore topn 200 130 #从大到小查找所有成员(注意,从大到小时第一个值必须大于等于第二个)
    zincrby topn 15 xiaohong #给小红添加15分
    zrem topn xiaohong #删除元素
    zcount topn 10 200 #统计该集合,分数区间内的元素个数
    zrank topn xiaohong #xiaohong的排名,从0开始
    
  • zset底层数据结构
    • hash结构
    • 跳跃表 给元素value排序,根据score的范围获取元素列表
    • 对比有序链表和跳跃表
      • 查找51元素
      • 跳跃表
        按图中的顺序查找,查找四次就能找到
  • End

redis_尚硅谷_01-05

课程简介 #

NoSQL数据库简介、Redis概述与安装、常用五大数据结构、配置文件详解、发布与订阅、Redis6新数据类型、Redis与spring boot整合、事务操作、持久化之RDB、持久化之AOF、主从复制及集群、Redis6应用问题(缓存穿透、击穿、雪崩以及分布式锁)、Redis6新增功能

NoSQL数据库简介 #

  • Redis属于NoSQL数据库
  • 技术分为三大类
    • 解决功能性问题:Java、Jsp、RDBMS、Tomcat、Linux、JDBC、SVN
    • 解决扩展性问题:Struts、Spring、SpringMVC、Hibernate、Mybatis
    • 解决性能问题:NoSQL、Java线程、Nginx、MQ、ElasticSearch
  • 缓存数据库的好处
    • 完全在内存中,速度快,结构简单
    • 作为缓存数据库:减少io的读操作
  • NoSQL=Not Only SQL,不仅仅是SQL,泛指非泛型数据库
    • 不支持ACID(但是NoSQL支持事务)
    • 选超于SQL的性能
  • NoSQL适用场景
    • 对数据高并发的读写
    • 海量数据的读写
    • 对数据高可扩展性
  • NoSQL不适用的场景
    • 需要事务支持
    • 基于sql的结构化查询存储
  • 多种NoSQL数据库介绍
    • Memcache 不支持持久化,数据类型单一,一般作为辅助持久化的数据库
    • Redis 支持持久化,除了k-v模式还有其他多种数据结构,一般作为辅助持久化的数据库
    • MongoDB,是文档型数据类型;k-v模型,但是对value提供了丰富的查询功能;支持二进制数据及大型对象;替代RDBMS,成为独立数据库
  • 大数据时代(行式数据库、列式数据库)
    • 行式数据库
      查询某一块数据的时候效率高
    • 列式数据库
      查询某一列统计信息快
    • 其他
      Hbase,Cassandra,图关系数据库(比如社会关系,公共交通网等)
  • 小计
    NoSQL数据库是为提高性能而产生的非关系型数据库

Redis概述与安装 #

  • 简单概述
    • Redis是一个开源的kv存储系统
    • 相比Mencached,支持存储的数据类型更多,包括string,list,set,zset以及hash,这些类型都支持(pop、add/remove及取交并集和差集等),操作都是原子性的
    • Redis数据都是缓存在内存中
    • Redis会周期性地把数据写入磁盘或修改操作写入追加的记录文件
    • 能在此基础上实现master-slave(主从)同步
  • Redis功能
    • 配合关系型数据库做高速缓存
    • Redis具有多样的数据结构存储持久化数据
    • 其他部分功能
  • Redis安装
    • 从官网中下载redis-6.xx.tar.gz包(该教程在linux中使用redis6教学)
    • 编译redis需要gcc环境
      • 使用gcc –version查看服务器是否有gcc环境
      • 如果没有需要进行安装
        apt install -y gcc
        或者
        yum install -y gcc
        
    • 将redis压缩文件进行解压
      tar -zxvf redis-6xx.tar.gz
      
    • 进入解压后的文件夹,并使用make命令进行编译
      make
      
    • 如果报错了,需要先用下面命令清理,之后再进行编译
      make distclean
      
    • 安装redis
      make install
      
    • 进入/usr/local/bin目录,查看目录
  • Redis启动
    • 前台启动
      redis-server 
      
    • 后台启动
      • 在刚才解压的文件夹中,拷贝出redis.conf文件(这里拷贝到/etc/目录下)
        cp redis.conf /etc/redis.conf
        
      • 到etc中修改redis.conf文件
        vim /etc/redis.conf
        # 进入编辑器后使用下面命令进行搜索并回车
        /daemonize no
        
        将no改为yes并保存
    • 进入/usr/local/bin目录启动redis
      redis-server /etc/redis.conf 
      
    • 查看进程,发现redis已经启动
      ps -ef | grep redis
      
    • 使用redis-cli 客户端连接redis
      redis-cli
      keys * 
      

相关知识 #

  • Redis6379的由来
    • 人名Merz 在九宫格对应的数字就是6379
  • Redis默认有15个库,默认数据都在数据库0中,所有库的密码都是相同的
  • Redis是单线程+多路复用技术
    • Redis是串行操作
    • 火车站的例子
      当1,2,3没有票的时候,不用一直等待买票,可以继续做自己的事情,黄牛买到票就会通知123进行取票
  • Memcached和Redis区别
    • Memcached支持单一数据类型,Redis支持多数据类型
    • Memcached不支持持久化
    • Memcached用的多线程+锁的机制,Redis用的是单线程+多路复用程序

End #