Fork me on GitHub

Linux Day06 redis

Day06


什么是NOSQL?

全称not only sql
为了解决高并发、高可用、高可扩展,海量数据存储一系列问题数据库解决方案。
nosql:弥补关系型数据库的瓶颈,但不是代替关系型数据库;

NOSQL分类

键值(key-value)存储数据库

产品:Redis、
应用:内存缓存,主要用于处理大量数据的高访问负载;
数据模型:一系列键值对
优势:快速查询
劣势:存储的数据缺少结构化

列存储数据库

应用场景:在分布式文件系统之上提供支持随机读写的分布式数据存储
典型产品:HBase、Hypertable、Cassandra、
数据模型:以‘列’为中心进行存储,将同一列数据存储在一起
优点:快速查询、高可扩展性、易于实现分布式扩展

文档数据库

应用场景:非强事务需求的web应用
典型产品:MongoDB、ElasticSearch、CouchDB、CouchBase Server
数据模型:键值模型,存储为文档
优点:数据模型无需事先定义

图式数据库

应用场景:社交网络、推荐系统、关系图谱
典型产品:Neo4J、Infinite Graph
数据模型:图式结构
优点:适用于图式计算场景;

redis 与 memcached的区别

  1. redis提供持久化存储方案,memcache无法持久化
  2. redis的数据类型多;

redis

什么是redis

redis是使用c语言开发的一个高性能键值数据库。拥有比较丰富的数据类型,用于存储数据。

数据类型

String 类型
hash 类型
list 类型
set 类型
sortedset 类型

应用场景

应用缓存(数据查询、短连接、新闻内容、商品内容等等)。
分布式集群的session分离。
任务队列(秒杀、抢购、12306等)。

下载和安装redis

下载

官网: http://redis.io / http://redis.cn
下载地址:http://download.redis.io/releases/
rpm包下载地址:https://pkgs.org/

安装步骤

  1. 上传redis到linux系统

  2. 解包并解压缩

    [root@hdp01 ~]# tar -zxvf redis-3.2.6.tar.gz -C /usr/local/
    
    
  3. 安装编译器环境

    yum install -y gcc-c++
    
  4. 编译安装

    [root@hdp01 ~]# cd /opt/redis-3.2.6/
    [root@hdp01 redis-3.2.6]# make
    [root@hdp01 redis-3.2.6]# make install PREFIX=/usr/local/redis
    # 如果编译出错使用 make distclean 清理
    # 默认安装路径/usr/local/bin
    

    redis目录下:
    ​ redis.conf:redis配置文件
    ​ src/redis-trib.rb:集群管理器

  5. 将配置文件拷贝到/etc目录下

    [root@hdp01 redis-3.2.6]# cp redis.conf /etc/
    
  6. 配置环境变量

    [root@hdp01 src]# vim /etc/profile.d/redis.sh
    [root@hdp01 src]# source /etc/profile.d/redis.sh
    [root@hdp01 src]# cat /etc/profile.d/redis.sh
    export REDIS_HOME=/usr/local/redis
    export PATH=$PATH:$REDIS_HOME/bin
    

redis启动

前端启动

  1. 启动服务器端

    [root@hdp01 bin]# ./redis-server
    

    默认端口6379

  2. 启动客户端,需要重新启动一个终端

[root@hdp01 bin]# ./redis-cli 
127.0.0.1:6379> 

     # -h: 指定ip
     # -p: 指定端口
  1. 如何关闭redis服务

    ctrl+c
    [root@hdp01 bin]# redis-cli shutdown
    [root@hdp01 bin]# kill -9 REDIS_PID
    

后端启动

  1. 修改配置文件

    [root@hdp01 bin]# vim /etc/redis.conf
    bind 0.0.0.0
    daemonize yes # 设置为后台启动
    
  2. 启动服务端

    [root@hdp01 bin]# redis-server /etc/redis.conf
    
  3. 客户端启动连接

    [root@hdp01 bin]# redis-cli -h 192.168.2.101 -p 6379
    192.168.2.101:6379> 
    
  4. 关闭redis服务

    [root@hdp01 bin]# redis-cli -h 192.168.2.101 shutdown
    [root@hdp01 bin]# kill -9 REDIS_PID
    

图形界面客户端

Redis Desktop Manager

jedis连接(java连接redis客户端)

需要两个jar包commons-pool2-2.3.jarjedis-2.7.0.jar

单客户连接

@Test
public void testSingle(){
    // 1. 创建jedis对象
    Jedis jedis = new Jedis("192.168.2.101",6379);
    // 2. 获取数据(发送命令给redis)
    System.out.println(jedis.get("k1"));
    // 3. 释放资源
    jedis.close();
}

多客户连接(池连接)

@Test
public void testPool(){
    // 1. 创建jedis连接池
    JedisPool pool = new JedisPool("192.168.2.101", 6379);
    // 2. 从池中获取jedis连接
    Jedis jedis = pool.getResource();
    // 3. 打印数据
    System.out.println(jedis.get("k2"));
    // 4. 释放资源
    jedis.close();
    // 5. 释放池
    pool.close();
}

redis数据类型

redis命令中文手册

String类型

语法

# 设置数据
set key value

# 获取数据
get key

# 获取并赋新值
getset key value

# 设置/获取多个值
mset k1 v1 k2 v2
mget k1 k2

# 删除
del key

# 递增和递减
incr key(每次增加1)

decr key(每次递减1)

incrby key 2
decrby key 2

# 追加
append
# 获取长度
strlen

应用场景

主键自增

hash类型

语法

# 赋值
hset key field value

# 一次赋多个值
hmset key field value [field1 value1.....]

# 字段没有值时赋值
hsetnx key field value;
返回值为0,表示没有更新值;

# 获取值
hget key field

# 一次获取多个值
hmget key field field2.....

# 获取key所有字段的值
hgetall key

# 删除字段,返回值是字段的个数
hdel key field [field ....]


# 增加数字
hincrby  key field 2

# 只获取字段的值或字段名
hkeys key 
hvals key

# 查看字段个数
hlen key

# 查看所有key
keys 表达式

# 查看key是否存在
exists key 

# 查看字段是否存在
hexists key field

应用场景

存储商品信息;

list类型

list底层采用链表保存,从两端来操作数据

语法

# 添加数据
lpush key 列表值(value1 , value2)

rpush key 列表值 (value1, value2)

# 查看列表
lrange key start stop (0开始索引/-1结束索引)

# 删除元素
lpop/rpop key

# 获取长度
llen key

应用场景

商品评论列表

set类型

集合类型
集合类型:无序、不可重复
列表类型:有序,可重复

语法

# 添加元素
sadd key member [member.... ]

# 删除元素
sremkey member [ member.... ]

# 查看所有成员
smembers key

# 判断元素是否存在
sismember key member

# 并集
sunion key [key...]

# 交集
sinter key [key...]

# 差集
sdiff key [key...]

sorted set类型

有序集合,zset
唯一,而且可排序(通过权重)

语法

# 添加元素
zadd key score member [score member .....]

# 获取元素的分数
zscore key member

# 删除元素
zrem key member [ member...]

# 查看范围类的元素列表
zrange key start stop [withscores]

# 从大到小排列
zrevrange key start stop [withscores]

# 获取某个值在 name对应的有序集合中的排行(从 0 开始)
zrank key member  

# 排序
zrevrank key start stop

应用场景

销售排行榜

其他命令

# 根据匹配规则查询所有key
keys 

# 判断某个元素是否存在
exists 

# 查看数据的类型
type

# 设置key的声明周期,单位是秒
EXPIRE(key,ttl) 
ttl key # 获取key的活动时间



持久化方案

rdb持久化

默认的持久化方案。文件保存在安装目录/bin/dump.rdb
配置文件中save的配置,说明了保存的时间间隔;

save 900 1 
save 300 10
save  60 10000

dbfilename dump.rdb # 持久化文件名

dir ./   # 创建dump.db的目录

可能会丢失最后一次操作

aof持久化(append only file)

aof保存每一次写操作的命令,默认关闭

appendonly yes  # 开启aof
apendfilename "appendonly.aof"  # aof的文件名
appendfsync everysec
no-appendfssync-on-rewrite no  建议改成yes
auto-aof-rewrite-percentage 100  增长率达到100%,
auto-aof-rewrite-min-size 64mb   重写要求达到64M时才会重写;

aof可以和rdb共存,但是aof生效,rdb默认读取aof文件;

主从复制

  1. master 无需配置

  2. slaver 修改配置文件

    daemonize yes
    bind 0.0.0.0
    slaveof MASTER_IP MASTER_PORT
    port 6379 # 可以不修改
    
  3. slaver的特点

    1. 只能读不能写
    2. 实时同步

redis集群搭建

redis集群架构图

投票机制

  1. 判断一个节点是否fail
    超过半数的节点无法访问
  2. 集群是否fail
    1. 如果master fail,但是没有slaver,此时集群fail
    2. 超过半数的master fail,此时集群fail

搭建集群

  1. 安装ruby,redis_trib.rb集群管理器;使用ruby语言编写,首先需要安装ruby环境

    [root@hdp01 bin]# yum install -y ruby rebygems
    
  2. 安装redis和ruby的接口

    [root@hdp01 bin]# gem install redis-3.0.0.gem 
    
  3. 准备集群管理器和6个redis服务器

    1. 创建集群目录:mkdir /usr/local/redis/cluster

    2. 复制集群管理器:[root@hdp01 src]# cp redis-trib.rb /usr/local/redis/cluster/

    3. 准备6个redis:

      1. 修改配置文件cluster-enabled yes,修改端口,后台运行等参数
      2. 启动6个redis,如果for i in {6379..6384}; do redis-server ${i}/redis.conf ; done不能启动所有的redis,那么就需要进入到每个redis目录手动启动
    4. 创建集群

    5. 连接集群

      [root@hdp01 cluster]# redis-cli -h 192.168.2.101 -p 6379 -c
      192.168.2.101:6379> cluster info
      cluster_state:ok
      cluster_slots_assigned:16384
      cluster_slots_ok:16384
      cluster_slots_pfail:0
      cluster_slots_fail:0
      cluster_known_nodes:6
      cluster_size:3
      cluster_current_epoch:6
      cluster_my_epoch:1
      cluster_stats_messages_sent:569
      cluster_stats_messages_received:569
      192.168.2.101:6379> cluster nodes
      18feea8ad25e2fb3309f74e8f71d6cee8e35adee 192.168.2.101:6383 slave 3b5380242932701343e087a470bf2ff862f59d8a 0 1541156981942 5 connected
      3b5380242932701343e087a470bf2ff862f59d8a 192.168.2.101:6380 master - 0 1541156975886 2 connected 5461-10922
      43e2200c46c0a6264157871fa735dfdabf2517c0 192.168.2.101:6384 slave f03acea2b67ebac654dd164bc4de334a2288311e 0 1541156981438 6 connected
      f03acea2b67ebac654dd164bc4de334a2288311e 192.168.2.101:6381 master - 0 1541156980934 3 connected 10923-16383
      519f866af82f180b3501a636a64f032bbf21a13b 192.168.2.101:6379 myself,master - 0 0 1 connected 0-5460
      109f576d10f0cfd9d0dd0e32cdbecf2ddcfbd3ee 192.168.2.101:6382 slave 519f866af82f180b3501a636a64f032bbf21a13b 0 1541156982952 4 connected
      
      

jedis连接redis集群

package jedis_cluster;

import java.util.HashSet;
import java.util.Set;

import org.junit.Test;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;

public class RedisTest {
	
	@Test
	public void redisTest(){
		// 创建jedisCluster
		Set<HostAndPort> nodes = new HashSet();
		nodes.add(new HostAndPort("192.168.2.101", 6379));
		nodes.add(new HostAndPort("192.168.2.101", 6380));
		nodes.add(new HostAndPort("192.168.2.101", 6381));
		nodes.add(new HostAndPort("192.168.2.101", 6382));
		nodes.add(new HostAndPort("192.168.2.101", 6383));
		nodes.add(new HostAndPort("192.168.2.101", 6384));
		JedisCluster cluster = new JedisCluster(nodes);
		cluster.set("s4", "44444");
		
		String result = cluster.get("s4");
		System.out.println(result);
		cluster.close();
	}
}

posted @ 2018-11-05 18:49  耳_东  阅读(103)  评论(0)    收藏  举报