内存数据库

基于内存的nosql数据库:Memchched,Redis

常见的内存数据库:

Memchched可以看成是redis的前身,严格来说,memcached不是数据库,只能叫缓存,不支持持久化。

Redis:内存数据库,支持持久化(RDB,AOF)

Oracle TimesTen:内存数据库(使用少)

内存数据库作用:快

Redis 和 memory cache 的区别

区别:
1. 性能:

redis 只能使用单核,而 memory cache 可以使用多核,所以在比较上,平均每一个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起Memcached,还是稍有逊色。说了这么多,结论是,无论你使用哪一个,每秒处理请求的次数都不会成为瓶颈。(比如瓶颈可能会在网卡)

2. 内存利用率:

如果要说内存使用效率,使用简单的key-value存储的话,Memcached的内存利用率更高,而如果Redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于Memcached。当然,这和你的应用场景和数据特性有关。

3. 数据持久化和数据同步

如果你对数据持久化和数据同步有所要求,那么推荐你选择Redis,因为这两个特性Memcached都不具备。即使你只是希望在升级或者重启系统后缓存数据不会丢失,选择Redis也是明智的。

4. 具体应用需求

当然,最后还得说到你的具体应用需求。Redis相比Memcached来说,拥有更多的数据结构和并支持更丰富的数据操作,通常在Memcached里,你需要将数据拿到客户端来进行类似的修改再set回去。这大大增加了网络IO的次数和数据体积。在Redis中,这些复杂的操作通常和一般的GET/SET一样高效。所以,如果你需要缓存能够支持更复杂的结构和操作,那么Redis会是不错的选择。

Memchched

memchched的基本原理架构

​ 在内存中维护了一张巨大的Hash表

​ memcached是可以搭建集群,是非常轻量级的,是可以在同一个服务上启动多个memcached

安装memcached

​ 1.需要使用gcc编译器,查看是否有gcc,gcc是c语言在Linux上面的编译器

​ 如果没有gcc使用yum安装

​ yum -y install gcc

​ 查案gcc的版本

​ gcc --version

​ 2.安装依赖:libevent库

​ (1)检测是否有libevent

​ rpm -qa | grep libevent

​ (2)如果检测有libevent删除这个libevent

​ rpm -e libevent

​ (3)安装包上传Linux:课件中下载

​ (4)解压安装包(源码包)

​ tar -zxvf ./soft/libevent-2.0.21-stable.tar.gz -C ./

​ (5)指定一个编译安装的路径

​ ./configure --prefix=/opt/libevent

​ (6).编译

​ make (调用c语言编译器,编译成.0的文件)

​ (7)安装

​ make install

​ 3.安装memcached

​ (1)解压安装包

​ tar -zxvf ./soft/memcached-1.4.25.tar.gz -C ./

​ (2)指定安装的路径

​ ./configure --prefix=/opt/memcached --with-libevent=/opt/libevent

​ (3)编译

​ make

​ (4)安装

​ make install

​ 4.启动memcached

​ ./memcached -u root -d -m 128 -p 11211

​ -d 守护线程(类似于后台启动)

​ -m 内存的大小

​ -p 端口号

​ -u 指定启动的用户,注意如果是由root用户启动时,必须指定

​ 查看是否启动成功

ps -ef | grep memcached
root       9712      1  0 04:44 ?        00:00:00 ./memcached -u root -d -m 128 -p 11211
root       9732   2479  0 04:44 pts/0    00:00:00 grep --color=auto memcached

操作Memcached

​ 命令方式:

​ 使用telnet写入数据

​ 查看是否安装telnet:rpm -qa | grep telnet

​ 安装:yum -y install telnet

​ 使用:telnet 192.168.2.111 11211

[root@bigdata111 bin]# telnet 192.168.2.111 11211
Trying 192.168.2.111...
Connected to 192.168.2.111.
Escape character is '^]'.
add key 0 0 4
abcd
STORED

#add key 0 0 4
#解释:
#add	添加数据的命令
#key	数据的key,自己指定
#0	是一个标志位,不用关心
#0	代表数据过期的时间,如果为0表示不过期
#4	代表数据的长度

get key
VALUE key 0 4
abcd
END

stats
STAT pid 9712
STAT uptime 771
STAT time 1587243412
STAT version 1.4.25
STAT libevent 2.0.21-stable
STAT pointer_size 64
STAT rusage_user 0.003562
STAT rusage_system 0.017813
STAT curr_connections 10
STAT total_connections 11
STAT connection_structures 11
STAT reserved_fds 20
STAT cmd_get 1
STAT cmd_set 2
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 1
STAT get_misses 0
STAT delete_misses 0
STAT delete_hits 0
STAT incr_misses 0
STAT incr_hits 0
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT touch_hits 0
STAT touch_misses 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 60
STAT bytes_written 70
STAT limit_maxbytes 134217728
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT time_in_listen_disabled_us 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 524288
STAT hash_is_expanding 0
STAT malloc_fails 0
STAT bytes 72
STAT curr_items 1
STAT total_items 1
STAT expired_unfetched 0
STAT evicted_unfetched 0
STAT evictions 0
STAT reclaimed 0
STAT crawler_reclaimed 0
STAT crawler_items_checked 0
STAT lrutail_reflocked 0
END

​ java API 操作

需要在idea中配置环境:

​ 需要将memcached的jar添加到idea中,可以使用离线的方式直接添加

package day0418;

import net.spy.memcached.MemcachedClient;

import java.io.IOException;
import java.io.Serializable;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

public class Demo {
    public static void main(String[] args) throws InterruptedException, ExecutionException, IOException {
        adds();
    }
    /**
     * 向memcached中添加数据
     * */
    public static void addMemcached() throws IOException, ExecutionException, InterruptedException {
        //创建memcached实例,指定服务器的IP地址和端口号
        MemcachedClient client = new MemcachedClient(
                new InetSocketAddress("192.168.2.111",11211));
        //添加数据
        Future<Boolean> f =  client.set("key1",0,"day0418");
        //关闭客户端
        if(f.get().booleanValue()){
            client.shutdown();
        }

    }

    /**
     * 读取Memcached的数据
     * */
    public static void getMem() throws IOException {
        //创建memcached实例,指定服务器的IP地址和端口号
        MemcachedClient client = new MemcachedClient(
                new InetSocketAddress("192.168.2.111",11211));
        //获取数据,通过key获取value
        Object o = client.get("key1");
        System.out.println("key1的值:"+o);
        client.shutdown();
    }
    /**
     * 向Memcached中添加类
     * */
    public static void addStudentMem() throws IOException, ExecutionException, InterruptedException {
        //创建memcached实例,指定服务器的IP地址和端口号
        MemcachedClient client = new MemcachedClient(
                new InetSocketAddress("192.168.2.111",11211));

        //添加数据
        Future<Boolean> future = client.set("key3",0,new Student());
        //关闭客户端
        if (future.get().booleanValue()){
            client.shutdown();
        }
    }

    /**
     * 向Memcached集群中添加数据
     * */
    public static void adds() throws IOException, InterruptedException {
        //创建连接集群
        List<InetSocketAddress> list = new ArrayList<InetSocketAddress>();
        list.add(new InetSocketAddress("192.168.2.111",11211));
        list.add(new InetSocketAddress("192.168.2.111",11212));
        list.add(new InetSocketAddress("192.168.2.111",11213));
        MemcachedClient client = new MemcachedClient(list);

        for(int i = 1; i <= 20 ; i++){
            System.out.println("插入第"+i+"个数据");
            client.set("key"+i,0,"value"+i);
            Thread.sleep(1000);
        }

        client.shutdown();
    }
}


class Student implements Serializable{}

Redis

Redis简介

redis的前身是Memcached

redis和Memcached区别:

​ 支持持久化:RDB快照,AOF日志

​ 支持丰富的数据类型

Redis安装

​ (1)解压安装

​ tar -zxvf ./soft/redis-3.0.5.tar.gz -C ./

​ (2)编译

​ make

​ (3)安装及指定安装的路径

​ make PREFIX=/opt/redis install

​ redis中bin下命令的含义:

	redis-benchmark	redis提供压力测试的工具,模拟产生客户端压力
	
    redis-check-aof	检查aof日志文件

    redis-check-dump	检测RDB的文件

    redis-cli  启动redis客户端

    redis-sentinel  启动redis的哨兵

    redis-server	启动redis的服务器

​ 修改配置文件:redis.conf

42 daemonize no  将no改为yes(是否以后台方式启动)
50 port 6379  此端口是redis默认的,如果在同一个服务器启动多个redis需要修改
#启动redis服务端
[root@bigdata111 redis]# ./bin/redis-server ./redis.conf 
[root@bigdata111 redis]# ps -ef | grep redis
root      12816      1  0 06:04 ?        00:00:00 ./bin/redis-server *:6379
root      12820   2479  0 06:04 pts/0    00:00:00 grep --color=auto redis

redis的操作:不作为重点

​ 命令

[root@bigdata111 redis]# ./bin/redis-cli 
127.0.0.1:6379> set key1 day0418
OK
127.0.0.1:6379> get key1
"day0418"
127.0.0.1:6379> get key
(nil)
127.0.0.1:6379> keys *
1) "key1"
127.0.0.1:6379> set key1 day0418
OK
127.0.0.1:6379> set key2 day0418
OK
127.0.0.1:6379> set key3 day0418
OK
127.0.0.1:6379> keys *
1) "key1"
2) "key3"
3) "key2"
127.0.0.1:6379>

Redis的事务

回顾关系型数据库的事务:

​ 事务是由一组DML语句组成

​ 事务的特点:要么成功,要么失败

​ 事务一些特性:ACID 原子性,一致性,隔离性,持久性

redis的事务本质:是将一组操作放在队列中,然后一次执行

Oracle事务和redis事务操作对比:

Oracle Redis
事务开启 自动开启 命令:multi
执行语句 DML Redis命令
事务提交 显式提交:commit,隐式提交:DDL语句(Create table) 命令:exec
事务回滚 显式回滚:Rollback,隐式回滚:系统断电,客户端退出,自动回滚 命令:discard将队列中的操作废弃

redis的事务不是真正的事务,是事务的模拟。

举例:

​ 模拟银行转账操作

127.0.0.1:6379> set zhangsan 2000
OK(操作成功)
127.0.0.1:6379> set lisi 2000
OK
127.0.0.1:6379> MULTI (开启事务)
OK
127.0.0.1:6379> decrby zhangsan 500
QUEUED(将操作放在队列中)
127.0.0.1:6379> incrby lisi 500
QUEUED
127.0.0.1:6379> exec(执行事务)
1) (integer) 1500
2) (integer) 2500
127.0.0.1:6379> get zhangsan
"1500"
127.0.0.1:6379> get lisi
"2500"