linux安装redis 完整步骤

最近在linux服务器上需要安装redis,来存放数据,增加用户访问数据的速度,由于是第一次安装,于是在百度上搜了一篇文章,按照这篇博客,顺利安装好了,因此将博主的文章拷过来记录一下,方便以后使用,也为需要的朋友提供一个方便,

参考博文地址:https://www.cnblogs.com/lauhp/p/8487029.html

 

安装:

1.获取redis资源

  wget http://download.redis.io/releases/redis-4.0.8.tar.gz

2.解压

  tar xzvf redis-4.0.8.tar.gz

3.安装

  cd redis-4.0.8

  make

  cd src

  make install PREFIX=/usr/local/redis

4.移动配置文件到安装目录下

  cd ../

  mkdir /usr/local/redis/etc

  mv redis.conf /usr/local/redis/etc

 5.配置redis为后台启动

  vi /usr/local/redis/etc/redis.conf //将daemonize no 改成daemonize yes

6.将redis加入到开机启动

  vi /etc/rc.local //在里面添加内容:/usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf (意思就是开机调用这段开启redis的命令)

7.开启redis

  /usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf 

 

常用命令  

  redis-server /usr/local/redis/etc/redis.conf //启动redis

  pkill redis  //停止redis

  卸载redis:

    rm -rf /usr/local/redis //删除安装目录

    rm -rf /usr/bin/redis-* //删除所有redis相关命令脚本

    rm -rf /root/download/redis-4.0.4 //删除redis解压文件夹

 

 

8-启动redis:

两种方式:

redis-server &

 

加上`&`号使redis以后台程序方式运行

或者是

 

redis-server

 

9-检测后台进程是否存在

 

ps -ef |grep redis

10-检测6379端口是否在监听

 

netstat -lntp | grep 6379

有时候会报异常

原因: Redis已经启动

解决: 关掉Redis,重启即可

 

 
  1. redis-cli shutdown

  2. redis-server

然后你就能看到Redis愉快的运行了.

 

使用redis-cli客户端检测连接是否正常

 

 
  1. redis-cli

  2. 127.0.0.1:6379> keys *

  3. (empty list or set)

  4. 127.0.0.1:6379> set key "hello world"

  5. OK

  6. 127.0.0.1:6379> get key

  7. "hello world"

 

停止redis:

使用客户端

 

redis-cli shutdown

因为Redis可以妥善处理SIGTERM信号,所以直接kill -9也是可以的

 

kill -9 PID

 

#启动redis服务端
$ src/redis-server
 
 
#启动redis客户端
$ src/redis-cli

 

 

Redis客户端常见操作

Redis是key-value数据库,支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。

  • 当value是string类型,命令包括set get setnx incr del 等。

> set server:name "fido"  // 设置键值
OK
> get server:name  // 获取键值
"fido"
> setnx connections 10   // set if not exists
OK
> incr connections   // 原子性增加values值
(integer) 11
> incr connections
(integer) 12
> del connections  // 删除key
(integer) 1
> incr connections
(integer) 1

 

当value是list类型,命令包括rpush lpush llen lrange lpop rpop del 等。

 

> rpush friends "Alice"   // 在末尾追加
(integer) 1
> rpush friends "Bob"
(integer) 2
> lpush friends "Sam"    // 插入到开头
(integer) 3
 
> lrange friends 0 -1     // 返回列表的子集,类似切片操作
1) "Sam"
2) "Alice"
3) "Bob"
> lrange friends 0 1
1) "Sam"
2) "Alice"
> lrange friends 1 2
1) "Alice"
2) "Bob"
 
> llen friends   // 返回列表长度
(integer) 3
> lpop friends   // 删除并返回列表第一个元素
"Sam"
> rpop friends   // 删除并返回列表最后一个元素
"Bob"
> lrange friends 0 -1
1) "Alice"
 
> del friends    // 删除key
(integer) 1     // 1表示成功,0表示失败

 

当value是set类型,命令包括sadd srem sismember smembers sunion del等。

> sadd superpowers "flight"     // 添加元素
(integer) 1
> sadd superpowers "x-ray vision"
(integer) 1
> sadd superpowers "reflexes"
(integer) 1
> srem superpowers "reflexes"   // 删除元素
1
 
> sismember superpowers "flight"   // 测试元素是否在集合中
(integer) 1
> sismember superpowers "reflexes"
(integer) 0
> smembers superpowers    // 返回集合中所有元素
1) "x-ray vision"
2) "flight"
 
> sadd birdpowers "pecking"
(integer) 1
> sadd birdpowers "flight"
(integer) 1
> sunion superpowers birdpowers    // 合并多个set,返回合并后的元素列表
1) "x-ray vision"
2) "flight"
3) "pecking"
 
> del superpowers   // 删除key

(integer) 1

 

当value是zset类型,命令包括 zadd zrange del等,注意给value一个编号用于排序。

> zadd hacker 1940 "Alan Kay"     // 给value指定一个编号,比如以年份1940作为编号
(integer) 1
> zadd hacker 1906 "Grace Hopper"
(integer) 1
> zadd hacker 1953 "Richard Stallman"
(integer) 1
> zadd hacker 1965 "Yukihiro Matsumoto"
(integer) 1
> zadd hacker 1916 "Claude Shannon"
(integer) 1
> zadd hacker 1969 "Linux Torvalds"
(integer) 1
> zadd hacker 1957 "Sophie Wilson"
(integer) 1
> zadd hacker 1912 "Alan Turing"
(integer) 1
 
> zrange hacker 2 4    // 切片返回有序集合中元素
1) "Claude Shannon"
2) "Alan Kay"
3) "Richard Stallman"
 
> del hacker    // 删除key

(integer) 1

 

当value是hash类型,hash类型可以理解为字典,需要给value指定一个field用于映射,命令包括hset hmset hget hgetall hdel hincrby del 等。

 

> hset user:1000 name "John Smith"   // 给value指定一个field,比如name
(integer) 1
> hset user:1000 email "john.smith@example.com"
(integer) 1
> hset user:1000 password "s3cret"
(integer) 1
> hgetall user:1000   // 获得hash表中所有成员,包括field和value
1) "name"
2) "John Smith"
3) "email"
4) "john.smith@example.com"
5) "password"
6) "s3cret"
 
> hmset user:1001 name "Mary Jones" password "hidden" email
"mjones@example.com"   // 设置多个field和value
OK
> hget user:1001 name   // 根据field获取value
"Mary Jones"
  
> hset user:1000 visits 10    // field可以映射到数字值
(integer) 1
> hincrby user:1000 visits 1    // 原子性增加value的值,增加1
(integer) 11
> hincrby user:1000 visits 10    // 增加10
(integer) 21
> hdel user:1000 visits      // 删除field及其value
(integer) 1
> hincrby user:1000 visits 1
(integer) 1
 
> del user:1000     // 删除key

(integer) 1

 

设置和查看key的生命周期,key过期会被自动删除,命令包括expire ttl 等。

> set resource:lock "Redis Demo"
OK
> expire resource:lock 120   // 设置生命周期为120s
(integer) 1
> ttl resource:lock   // 查看当前生命周期还剩多少时间
(integer) 109
> ttl resource:lock   // 120s后查看,返回-2表示已过期或不存在
(integer) -2
 
> set resource:lock "Redis Demo 2"
OK
> ttl resource:lock    // 返回-1表示永不过期
(integer) -1

 

 

 

查看linux上面是否有安装redis,redis启动

 

1、检测是否有安装redis-cli和redis-server;

 
  1. [root@localhost bin]# whereis redis-cli

  2. redis-cli: /usr/bin/redis-cli

  3.  
  4. [root@localhost bin]# whereis redis-server

  5. redis-server: /usr/bin/redis-server

 

 

Linux系统下设置redis的密码

Linux系统下设置redis的密码:

1、进入redis操作的命令行

运行命令:redis-cli

 

2、查看现有的redis密码(可选操作,可以没有)

运行命令:config get requirepass如果没有设置过密码的话运行结果会如下图所示

 

3、设置redis密码

运行命令:config set requirepass ****(****为你要设置的密码),设置成功的话会返回‘OK’字样

 

4、重启redis服务

ctrl+C退出当前的命令行模式后运行命令:

redis-cli -h 127.0.0.1 -p 6379 -a ****(****为你心设置的密码)

 

 

 

 

SpringBoot整合Redis及Redis工具类撰写

提前说明:

注意:JavaBean必须实现序列化,不然数据无法存入Redis。
public class User implements Serializable

1.SpringBoot集成Redis实现缓存

首先需要引入SpringBoot的Redis依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

关键代码:

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    /**注入SpringBoot自动配置好的redisTemplate**/
    //注意:spring boot帮我们注入的redisTemplate类,泛型里面只能写 <String, String>、<Object, Object>,不能一个String一个Object!
    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    @Override
    public List<User> findAllUser() {

        //字符串的序列化器(这里只将key序列化--->AllUser),为了在Redis管理工具更好看一点(AllUser不会出现前面的类似乱码的)
        RedisSerializer redisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(redisSerializer);

        //查询缓存
        List<User> userList = (List<User>) redisTemplate.opsForValue().get("AllUser");
        if (userList == null){
            //缓存为空,查询数据库
            userList = userMapper.findAllUser();
            //把查询出来的数据放入Redis中
            redisTemplate.opsForValue().set("AllUser",userList);
        }

        return userList;
    }

    @Override
    public User findUserById(Integer id) {

        //字符串的序列化器(这里只将key序列化--->AllUser),为了在Redis管理工具更好看一点(AllUser不会出现前面的类似乱码的)
        RedisSerializer redisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(redisSerializer);

        //查询缓存
        User user = (User) redisTemplate.opsForValue().get("User");
        if (user == null){
            //缓存为空,查询数据库
            user = userMapper.findUserById(id);
            //把查询出来的数据放入到Redis中
            redisTemplate.opsForValue().set("User",user);
        }

        return user;
    }
}

总结思路:

1.字符串序列化(名字)。
2.查询Redis缓存,如果为空,查询数据库。
3.将查询出来的数据放入Redis缓存中。
4.返回结果。

思考:

如果一万个人同时访问(高并发条件下),上面的代码是否有什么不恰当?

2.高并发下SpringBoot集成Redis缓存的问题

关键代码:

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    /**注入SpringBoot自动配置好的redisTemplate**/
    //注意:spring boot帮我们注入的redisTemplate类,泛型里面只能写 <String, String>、<Object, Object>,不能一个String一个Object!
    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    /**
     * 测试高并发问题
     * @param name
     * @return
     */
    @Override
    public List<User> findUserByName(String name) {

        //字符串的序列化器(这里只将key序列化--->AllUser),为了在Redis管理工具更好看一点(AllUser不会出现前面的类似乱码的)
        RedisSerializer redisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(redisSerializer);

        List<User> userList = (List<User>) redisTemplate.opsForValue().get("findByLikeName");

        if (userList == null){
            synchronized (this){
                //查询Redis缓存
                userList = (List<User>) redisTemplate.opsForValue().get("findByLikeName");
                if (userList == null){
                    //查询数据库
                    userMapper.findUserByName(name);
                    System.out.println("查询的数据库...");
                    //将查询的结果放入Redis缓存中
                    redisTemplate.opsForValue().set("findUserByName",userList);
                }else {
                    System.out.println("查询的缓存...");
                }
            }
            System.out.println("查询的缓存...");
        }

        return userList;
    }
}

Controller:

@Controller
public class UserController {

    @Autowired
    private UserService userService;


    /**
     * 高并发问题
     * @param name
     * @return
     */
    @RequestMapping("/findUserByName/{name}")
    @ResponseBody
    public List<User> findUserByName(@PathVariable("name") String name){

        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                userService.findUserByName(name);
            }
        };
        ExecutorService executorService = Executors.newFixedThreadPool(25);
        for (int i = 0; i < 10000; i++) {
            executorService.submit(runnable);
        }

        List<User> userList = userService.findUserByName(name);
        return userList;
    }
}

效果图:

可以看到查询数据的次数非常非常多,这样对数据库的压力十分大,甚至我查询不出结果!

3.解决高并发问题

关键代码:

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    /**注入SpringBoot自动配置好的redisTemplate**/
    //注意:spring boot帮我们注入的redisTemplate类,泛型里面只能写 <String, String>、<Object, Object>,不能一个String一个Object!
    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    /**
     * 测试解决高并发问题
     * @param id
     * @return
     */
    @Override
    public User findUserById(Integer id) {

        //字符串的序列化器(这里只将key序列化--->AllUser),为了在Redis管理工具更好看一点(AllUser不会出现前面的类似乱码的)
        RedisSerializer redisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(redisSerializer);

        //查询Redis缓存
        User user = (User) redisTemplate.opsForValue().get("User");

        //解决高并发问题:双重监测锁
        if (user == null){

            synchronized (this){

                //查询Redis缓存
                user = (User) redisTemplate.opsForValue().get("User");

                if (user == null){
                    //缓存为空,查询数据库
                    user = userMapper.findUserById(id);
                    System.out.println("查询的数据库...");

                    //把查询出来的数据放入到Redis中
                    redisTemplate.opsForValue().set("findUserById",user);
                }else {
                    System.out.println("查询的缓存...");
                }
            }
        }else {
            System.out.println("查询的缓存...");
        }

        return user;
    }


}

Controller:

@Controller
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 测试解决高并发问题
     * @param id
     * @return
     */
    @RequestMapping("/findUserById/{id}")
    @ResponseBody
    public User findUserById(@PathVariable("id") Integer id){

        //多线程,该线程调用底层根据id查询学生的方法
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                userService.findUserById(id);
            }
        };
        //多线程测试高并发条件下内网穿透问题
        ExecutorService executorService = Executors.newFixedThreadPool(25); //线程池根据CPU来选择适当的值
        for (int i = 0; i < 10000; i++) {
            //提交线程runnable方法
            executorService.submit(runnable);
        }

        User user = userService.findUserById(id);
        return user;
    }
}

效果图:

或者配置好Druid数据源:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值