Seven Lua Redis Redis and advanced practice of using the initial integration

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: https://blog.csdn.net/weixin_44018338/article/details/99573345

I. Introduction

        Redis school for some time, the basic things are not a problem. From speaking to write a number of related things and redis lua script today, lua script is a good thing, can run on any platform that can be embedded into most languages which, to extend its functionality. lua script is written in C language, the volume is very small, run fast, and each execution as an atomic transaction is executed, in which we can do a lot of things. Due to space a lot, not a an overview of all, you may want to write this series of articles in the form of, well, today we get to the bar.

Two, Lua Introduction
    
        Lua is a small scripting language. Brazil Pontifical Catholic University of Rio de Janeiro (Pontifical Catholic University of Rio de Janeiro ) in a research team from Roberto Ierusalimschy, Waldemar Celes, and Luiz Henrique de Figueiredo composed and developed in 1993. It is designed for embedded applications, thereby providing a flexible expansion and customization of applications. Lua written by the standard C made, almost all can be compiled on all operating systems and platforms, run. Lua does not provide a strong library, which is determined by its location. So Lua is not suitable as a stand-alone application development language. Lua has a JIT project simultaneously, providing real-time compilation on a specific platform.

       Lua scripts can easily be called C / C ++ code can turn call the function C / C ++, which makes Lua in your application can be widely used. Not only as an extension script can be used as a normal configuration file, instead of XML, ini file format, and easier to understand and maintain. Written by Lua from standard C code is simple and beautiful, almost all can be compiled on all operating systems and platforms, run. A complete Lua interpreter but 200k, all in the current script engine, Lua is the fastest speed. All this determines the Lua script is embedded as the best choice.

Third, the benefits of using Lua script

       1, reducing network overhead: a plurality of requests can be sent through the form of a script, reduce network latency and the number of requests.

       2, atomic operations: Redis entire script will be executed as a whole, can not be inserted into the middle of other commands. Therefore, in the process of writing the script without worrying about race conditions occur, without the use of a transaction.

       3, code reuse: the client sends the pace will be permanently present in redis, so that other clients can reuse the script to accomplish the same logic.

       4, speed: See performance compared with other languages, as well as a JIT compiler can significantly improve the performance of most tasks; for those who are still not satisfied with the performance of people, you can use the key part of the C implementation, and its integration, this can also enjoy the benefits of other aspects.

       5, can be transplanted: As long as there is ANSI C compiler platform can be compiled, you can see that it can run on almost any platform: from Windows to Linux, Mac platform is also no problem, to the mobile platform game host, and even browser can also be the perfect use (translated to JavaScript).

       6, compact source code: 20000 lines of C code that can be compiled into an executable file 182K, loading fast, fast run.

Four, redis and Integrated explain lua

      1, calling Lua script syntax:
              $ Redis-cli --eval path / to / redis.lua KEYS [1] KEYS [2], ARGV [1] ARGV [2] ...

              - -eval, told redis-cli read and run behind the lua script
               path / to / redis.lua, is the location of lua script
               KEYS [1] KEYS [2] , is a key to be operated, can specify multiple, [1], KEYS [2 ] obtained by the KEYS lua script
               ARGV [1] ARGV [2] , the parameter in the script lua [1], ARGV [2] obtained by ARGV.

              Note: KEYS and ARGV middle ',' on both sides of the space, can not be omitted.

             redis supports most standard Lua libraries

Library name Explanation
Base Provide some basic functions
String It provides functions for string manipulation
Table It provides functions for operating table
Math Provide math functions
Debug It provides functions for debugging


       2, a command script invoked redis
               can redis.call function call commands in a script Redis

              redis.call ( 'SET', 'foo', 'bar')
              local redis.call value = ( 'GET', 'foo' ) --value value of bar

              redis.call return value of the function is the execution result of the command Redis

              return value of the command Redis five types, redis.call function will return the five types into corresponding data Lua type, the following specific mapping rules (special null result of the comparison, the corresponding Lua false)

               redis return type and data type conversion rules Lua

redis return type Lua data types
Integer reply Digital Type
String Reply String type
Multi-line strings Reply table type (an array form)
Status Reply type table (only a state information field stores ok)
Error reply table type (only one field for storing error err)


                  redis also provides redis.pcall function, function and redis.call same, the only difference is when the command execution error, redis.pcall logs an error and continues to execute, and return an error directly redis.call not continue. In the script you can use the return statement to return a value to the client, if not performed by default returns nil return statement

                  Lua return value data type and type conversion rules redis

Lua data types redis return type
Digital Type Integer reply (the Lua numeric types are automatically converted to an integer)
String type String Reply
table type (an array form) Multi-line strings Reply
type table (only a state information field stores ok) Status Reply
table type (only one field for storing error err) Error reply


        3, the script command associated
             EVAL syntax:  the eval Script numkeys key [key ...] arg [arg ...]

              is transmitted by the key and data to the script arg these two parameters, and their values KEYS using in the script are two ARGV table type of access a global variable.

              Script : a lua script

              numkeys : indicates there are several key, respectively KEYS [1], KEYS [2 ] ..., if the value numkeys + 1 from the first parameter value is a start, ARGV [1], ARGV [ 2] ...

             Note: EVAL command according to the parameter numkeys to be behind it all parameters are stored in a script KEYS table and ARGV two types of global variables. When the script without any parameters, can not omit this parameter (set to 0)

       192.168.127.128:6379>eval "return redis.call('set',KEYS[1],ARGV[1])" 1 name liulei
       OK

       192.168.127.128:6379>get name
       "liulei"


       4, EVALSHA command
              in the script is relatively long, if each call script will need to pass the entire script Redis will take up more bandwidth. To solve this problem, Redis provides EVALSHA command, allows developers to execute the script by SHA1 digest the contents of the script, and use the command EVAL, in that it is to replace the contents of the script to script content SHA1 digest.

             Redis calculates the script in the implementation of the EVAL command SHA1 digest and recorded in the script cache, Redis will look for when performing EVALSHA command according to a summary provided by the script cache script corresponding to the contents, if found then execute the script, otherwise it returns an error : ".. NOSCRIPT No matching script Please use EVAL"

             use EVALSHA command in the program in general procedure is as follows.

                 1), first calculate the SHA1 digest of the script, and use EVALSHA command script.

                 2) to obtain the return value, if the return "NOSCRIPT" error EVAL command is used to re-execute the script.

              Although this process a bit cumbersome, but the good news is that many programming languages Redis client terminal will replace the developer to complete the process. EVAL command is executed, the first attempt to execute EVALSHA command will fail if executed EVAL command.

               SCRIPTLOAD "lua-script" will be added to the script cache, but do not execute, return: the script SHA1 digest

               whether SCRIPT EXISTS lua-script-sha1 judge script has been cached

       5, SCRIPT FLUSH (the command is not case-sensitive)
               Empty Script cache, SHA1 digest redis will be preserved permanently added to the script to the script after the cache is not deleted, but you can manually use the SCRIPT FLUSH command script cache situation.

       192.168.127.128:6379>script flush
       OK

       192.168.127.128:6379>SCRIPT FLUSH
       OK


       6, SCRIPT KILL (This command is not case-sensitive)
              forced to terminate execution of the current script. However, if the current pace of implementation of the data were redis write operation, the SCRIPT KILL command will not terminate the script to prevent the script only been partially implemented. All commands in the script, or are executed or not executed.

Copy the code

       The kill 192.168.127.128:6379>script 
      (error) NOTBUSY No scripts in Execution right now 

      192.168.127.128:6379>SCRIPT KILL 
      (error) NOTBUSY No scripts in Execution right now 
       // This script is not currently in execution, it prompts the error

Copy the code


       7, lua-time-limit 5000 (redis.conf profile)

              In order to prevent a script execution time is too long resulting in Redis can not provide services (such as an endless loop), Redis provides lua-time-limit parameter limits the maximum run time script, the default is 5 seconds. When the script runs longer than this limit, Redis will begin to accept other commands but does not execute (to ensure atomicity of the script, because the script has not been terminated), but will return "BUSY" error.

Fifth, install and use Lua scripts

  1, the installation environment library lua

              1.1, -Y yum the install the readline
                     
              1.2, yum the install the readline-devel -Y

                     

        2, download the latest version Installation lua

                2.1, lua Quguan network download, download via wget, directly following address: http: / /www.lua.org/download.html

           [root@lunux~]# wget http://www.lua.org/ftp/lua-5.3.4.tar.gz /root/software/download/lua/

                         



               2.2, via ssh SSH Secure File Transfer Client tool, upload the package to a Linux server. Directory: / root / software / download / lua /

           [root @ linux ~] # cd ./software/download/lua/ 

           [root @ linux Contact] # tar zxvf take-5.3.4.tar.gz

                          

                        
                2.3, enter the directory lua-5.3.4 has been unpacked, ready to install the files.

Copy the code

            [root@linux lua]# ls

            [root@linux lua]# lua-5.3.4 lua-5.3.4.tar.gz

            [root@linux lua]# cd lua-5.3.4

            [root@linux lua-5.3.4]#

Copy the code


             2.4、准备安装环境,使用make linux命令,当前也是需要gcc命令的支持,事先必须安装,安装gcc命令:yum install gcc。

            [root@linux lua-5.3.4]# make linux


                        

            2.5、开始安装lua软件包,使用make install命令

            [root@linux lua-5.3.4]# make install

                        


           2. 6、最后进行测试,进到Linux的命令行,然后输入lua命令,开始测试。

Copy the code

          [root@linux lua-5.3.4]# lua

          >print('lua')
          lua

          >print("lua")
          lua

Copy the code

                    


            2.7、按Ctrl+C退出lua命令模式。

           >^C
          [root@linux lua-5.3.4]# 


           2.8、lua脚本文件名必须以.lua后缀名,如果在Linux命令行执行lua脚本,直接lua 脚本名称。

Copy the code

         [root@linux lua-5.3.4]# cd /root/application/program/   //执行文件都在这个目录里面

         [root@linux program]# mkdir luascript  //创建luaScript脚本目录,存放lua脚本文件

         [root@linux program]# cd luascript  

         [root@linux luascript]# lua 01.lua    //执行01.lua脚本文件

Copy the code


           2.9、redis与lua脚本结合使用,如果在lua脚本里使用了 redis.call命令来操作Redis,执行lua脚步如下面:

Copy the code

          //redis-cli和lua脚本的路径可以是相对路径,也可以是绝对路径
          //以下代码就是通过绝对地址来执行

          //绝对地址:
          [root@linux ~]# /root/application/program/redis-tool/redis-cli -h 192.168.127.128 -p 6379 --eval /root/application/program/luascript/02.lua

          //相对地址:
          //当前目录
          192.168.127.128:6379>pwd
          [root@linux redis-tool]/root/application/program/redis-tool/

          [root@linux redis-tool]# redis-cli -h 192.168.127.128 -p 6379 --eval /root/application/program/luascript/02.lua

Copy the code


            2.10、Redis客户端执行带有参数的lua脚本,脚本文件的名称是:03.lua。

Copy the code

           //当前redis 数据库中只有name和age两个key,其他数据已经清空。

           //当前所在目录
           192.168.127.128:6379>keys *
           1)"name"
           2)"age"

           192.168.127.128:6379>get name
           "liulei"

           192.168.127.128:6379>get age
           "15"
     

          //03.lua脚本代码如下:

           local name=redis.call("get",KEYS[1])

           local age=redis.call("get",KEYS[2])

           if name=="LLL" then

             redis.call("set",KEYS[1],ARGV[1])
 
             redis.call("incr",KEYS[2])
            end

          //执行改脚本的命令,必须在Linux的命令行,不是在Redis的命令行
          [root@linux ~]# /root/application/program/redis-tool/redis-cli -h 192.168.127.128 -p 6379 --eval /root/application/program/luascript/03.lua name age , patrickLiu

          //执行脚本命令后
          192.168.127.128:6379>keys *
          1)"name"
          2)"age"

          192.168.127.128:6379>get name
          "patrickLiu"

          192.168.127.128:6379>get age
          "16"

         //说明带参数的执行Lua脚本成功

Copy the code


             2.11、Redis客户端执行有参数lua,并返回lua的表类型。

Copy the code

            //04.lua文件的源码

            local b1=redis.call("hgetall",KEYS[1])
            return b1

            //代码很简单,话不多说

            //清空当前数据库
            192.168.127.128:6379>flushdb

            192.168.127.128:6379>keys *
            (empty list or set)

            192.168.127.128:6379>hmset myhash name zhangsan sex nan address hebeibaoding school laiyuanyizhong
            OK

            192.168.127.128:6379>hmget myhash name sex address school
            1)"zhangsan"
            2)"nan"
            3)"hebeibaoding"
            4)"laiyuanyizhong"

            //我们通过redis客户端获取myhash的结果,进入到redis客户端的当前目录

            [root@linux redis-tool]# redis-cli -h 192.168.127.128 -p 6379 --eval ../luascript/04.lua myhash
            1)"name"
            2)"zhangsan"
            3)"sex"
            4)"nan"
            5)"address"
            6)"hebeibaoding"
            7)"school"
            8)"laiyuanyizhong"

          //成功获取myhash的列表

 

Copy the code

Guess you like

Origin blog.csdn.net/weixin_44018338/article/details/99573345