Redis学习笔记

Posted 想成为大师啊

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis学习笔记相关的知识,希望对你有一定的参考价值。

Nosql概述

1、单机mysql的年代

90年代,一个基本网站的访问量一般不会太大,单个数据库完全足够了。那个时候,更多的去使用静态网页html,服务器根本没有太大压力

思考一下,这种情况:整个网站的瓶颈是什么?

  1. 数据量如果太大,一个机器放不下
  2. 数据的索引 300w就一定要建立索引,数据的索引(B+ Tree)一个机器内存也放不下
  3. 访问量(读写混合),一个服务器承受不了

只要开始出现以上的三种情况之一,那你必须要晋级了

Memcached(缓存)+ MySQL + 垂直拆分(读写分离)

网站80%的情况都是在读,每次都要去查询数据库的话就十分麻烦!所以说我们希望减轻数据的压力,我们可以使用缓存来保证效率!

发展过程:优化数据结构和索引 --> 文件缓存(IO操作)–> Memcached(当时最热门的技术)

分库分表 + 水平拆分 + MySQL集群

本质:数据库(读、写)

早些年数据库引擎采用 MyISAM:表锁,十分影响效率,高并发下就会出现严重的锁问题

现在数据库引擎采用 Innodb:行锁

慢慢的就开始使用分库分表来解决写的压力,MySQL在那个年代推出了表分区,这个并没有多少公司使用;MySQL的集群很好满足那个年代的所有需求

如今最近的年代

MySQL等关系型数据库就不够用了,数据量很多,变化很快

MySQL有的使用它存储一些比较大的文件、博客、图片,数据库表很大,效率就低了,如果有一种数据库来专门处理这种数据,MySQL压力就变得十分小(研究如何处理这些问题)大数据的IO压力下,表几乎没法更大 1亿

目前一个基本的互联网项目

为什么要用NoSQL

用户的个人信息(社交网络、地理位置、用户自己产生的数据、用户日志等等爆发式增长)这时候我们就需要使用NoSQL数据库的,NoSQL可以很好的处理以上的情况!

什么是NoSQL

NoSQL = No Only SQL(不仅仅是数据库)

泛指非关系型数据库的,随着web2.0互联网的诞生!传统的关系型数据库很难对付web2.0!尤其是超大规模的高并发的社区!暴露出来很多难以克服的问题,NoSQL在当今大数据环境下发展的非常迅速,Redis是发展最快的,而且是我们当下必须掌握的一个技术

很多的数据类型用户的个人信息、社交网络、地理位置。这些数据类型的存储不需要一个固定的格式;不需要多个操作就可以横向扩展的

NoSQL特点

  1. 方便拓展(数据之间没有关系,很好扩展!)

  2. 大数据量、高性能(Redis 一秒写8万次,一秒读11万次,NoSQL的缓存记录级,是一种细粒度的缓存,性能会比较高)

  3. 数据类型是多样型的(不需要事先设计数据库,随取随用,如果数据量十分大的表,很多人就无法设计了)

  4. 传统RDBMS 和 NoSQL

    传统的 RDBMS
    - 结构化组织
    - SQL
    - 数据和关系都存在单独的表中 row col
    - 操作,数据定义语言
    - 严格的一致性
    - .....
    
    NoSQL
    - 不仅仅是数据
    - 没有固定的查询语言
    - 键值对存储,列存储,文档存储,图形数据库(社交关系)
    - 最终一致性
    - CAP定理 和 BASE(异地多活)初级架构师
    - 三高问题(高性能、高可用、高可扩)
    - ...
    

了解:3V + 3高

大数据时代的 3V:主要是描述问题的

  1. 海量性 Volume
  2. 多样性 Variety
  3. 实时性 Velocity

大数据时代的 3高:主要是对程序的要求

  1. 高并发
  2. 高可扩(随时水平拆分,机器不够了,可以扩展机器来解决)
  3. 高性能(保证用户体验和性能)

真正在公司中的实践:NoSQL + RDBMS 一起使用才是最强的,阿里巴巴架构演进


阿里巴巴架构演进

开源才是技术的王道!!!

任何一家互联网的公司,都不可能只是简简单单让用户能用就好了

大量公司做的都是相同的业务(竞品协议)

随着这样的竞争,业务是越来越完善,然后对于开发者的要求也是越来越高!

Redis入门

redis会周期性的把更新的数据写入磁盘或者把修改写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。免费和开源!是当下最热门的NoSQL技术之一!也被人们称之为结构化数据库

redis能干嘛

  1. 内存存储、持久化,内存中是断电即失,所以持久化很重要(RDB、AOF)
  2. 效率高,可以用于高速缓存
  3. 发布订阅系统
  4. 地图信息分析
  5. 计时器、计数器(浏览量)

特性

  1. 多样的数据类型
  2. 持久化
  3. 集群
  4. 事务

测试性能

redis-benchmark 是一个压力测试工具

官方自带的性能测试工具

redis-benchmark 命令参数

简单测试如下:

// 测试:100个并发连接   100000请求
redis-benchmark -h localhost -p 6379 -c 100 -n 100000

基础知识

redis默认有16个数据库,默认使用的是第0个数据库(可以使用select进行切换)

select 3 	// 切换数据库
DBSIZE		// 查看数据库的大小
keys *		// 查看数据库的所有数据
flushdb		// 清除当前数据库
flushall	// 清除全部数据库内容

思考:为什么redis的默认端口是6379

Redis是单线程的

Redis是很快的,官方表示,Redis是基于内存操作,CPU不是Redis性能瓶颈,Redis的瓶颈是根据机器的内存和网络带宽,既然可以使用单线程来实现,就使用单线程,所以就使用单线程了

Redis是C语言写的,官方提供的数据为 100000+ 的QPS,完全不比同样是使用 key-value的Memcache差!

Redis为什么单线程还这么快?

  • 误区一:高性能的服务器一定是多线程的?
  • 误区二:多线程(CPU上下文会切换)一定比单线程效率高

核心:redis是将所有的数据全部放在内存中,所以说使用单线程去操作效率就是最高的,多线程(CPU上下文会切换:耗时的操作!!!),对于内存系统来说,如果没有上下文切换效率就是最高的!多次读写都是在一个CPU上的,在内存情况下,这个就是最佳的方案!


五大数据类型

String(字符串)

set key1 v1		// 设置key1的值为v1
get key1		// 获取key1的值
keys *			// 查看数据库内的所有数据
EXISTS key1		// 查看key1是否存在
APPEND key1 "hello"		// 向key1字符串后面追加 "hello"
STRLEN key1		// 查看key1的长度
ttl key1		// 查看离过期所剩余的时间

set views 0
incr views	// 自增加一 (i++)
decr views	// 自减减一 (i--)
INCRBY views 10		// 增加10 (i+=10),可以指定增量
DECRBY views 10		// 减少10 (i-=10),可以指定减量

// 字符串范围 range
set key1 "hello"
GETRANGE key1 0 3	// "hell"	截取字符串 [0,3]
GETRANGE key1 0 -1	// 查看全部的字符串

// 替换
set key2 "abcdefg"
get key2	// abcdefg
SETRANGE key2 1 xx	// 替换指定位置开始的字符串
get key2	// axxdefg

// setex (set with expire)	设置过期时间
// setnx (set if not exist)	不存在在设置
setex key3 30 "hello"	// 设置key3的值为 hello 30秒过期
setnx mykey "redis"		// 如果mykey不存在,创建mykey
setnx mykey "MongoDB"	// 如果mykey存在,创建失败

// mset
// mget
mset k1 v1 k2 v2 k3 v3	// 设置 k1 k2 k3的值(同时设置多个值)
mget k1 k2 k3	// 获取k1 k2 k3的值(同时获取多个值)
msetnx k1 v1 k4 v4	// msetnx是一个原子性的操作, 要么一起成功, 要么一起失败
get k4	// 获取失败

// 对象
set user:1 name: zhangsan, age:3	// 设置一个user:1 对象 值为JSON字符来保存一个对象
// 这里的key是一个巧妙的设计: user:id:filed, 如此设计在Redis中完全OK

mset user:1:name zhangsan user:1:age 2
mget user:1:name user:1:age

// getset 先get再set
getset db redis		// 如果不存在值, 则返回nil
get db
getset db mongodb	// 如果存在值, 获取原来的值, 并设置新的值
get db

数据结构是相通的!!!

String类似的使用场景: value除了是我们的字符串还可以是我们的数字

  • 计数器
  • 统计多单位数量 uid:123123:follow 0
  • 粉丝数
  • 对象缓存存储

List

基本的数据类型,列表;在redis里面,我们可以把list玩成:栈、队列、阻塞队列

所有的list命令都是L开头的,Redis不区分大小命令

LPUSH list one	// 将一个值或多个值, 插入到列表头部
LPUSH list two
LPUSH list three
LRANGE list 0 -1	// 获取list内的所有值

Rpush list right	// 将一个值或多个值, 插入到列表尾部(右)

// LPOP 左移除
// RPOP 右移除
Lpop list	// 移除list的第一个元素
Rpop list	// 移除list的最后一个元素

Lindex list 1	// 通过下标获得list中的某一个值
Lindex list 0

// Llen
Llen list	// 返回列表的长度

// 移除指定的值
Lrem list 1 one		// 移除list集合中指定个数的value, 精确匹配
Lrem list 1 three	
Lrem list 2 three

// ltrim 修剪(截取)
ltrim mylist 1 2	// 通过下标截取指定的长度, 这个list已经被改变了

// rpoplpush	移除列表的最后一个元素, 将他移动到新的列表中
rpoplpush mylist myotherlist

以上是关于Redis学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

Redis学习笔记1:NoSQL是什么?

Node.js学习笔记

Redis学习笔记jedis(JedisCluster)操作Redis集群 redis-cluster

Redis学习笔记

Redis学习笔记Redis安装和启动

Redis6学习笔记(自用)